unordered_map::emplace学习

本文探讨了C++中unordered_map的emplace方法,强调其在原地构造元素且不涉及移动或复制的优势。emplace返回一个pair,包含插入位置的iterator,若key已存在则返回该key的iterator。此外,文章提到了Amortized复杂度为常数,最坏情况为线性。emplace适用于不需要额外构造参数的情况,而当key或value需要多个构造参数时,需要使用forward_as_tuple。此外,文章还讨论了unordered_map的相关成员函数,如size、max_size、bucket_count等,并解释了rehash和reserve的区别。最后,介绍了遍历unordered_map的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先不说insert与emplace之间的区别,只说emplace。emplace允许construct element in place without move or copy.使用forwarding和variadic template(可变模板)来forward arguments to the constructor of the key-value pair.

template<class... Args>
std::pair<iterator,bool> emplace(Args&&... args);
 The constructor of the new element (i.e. std::pair<const Key, T>) is called with exactly the same arguments as supplied to emplace, forwarded via std::forward<Args>(args)....

如上,返回类型是一个pair,包括一个iterator指向插入位置;如果emplace.first的key已经存在,不会插入,返回key所在的iterator;返回的pair.second是一个bool用来说明是否插入。

Amortized摊还复杂度为常数,最差可能是线性复杂度。

// uses pair's move constructor
    m.emplace(std::make_pair(std::string("a"), std::string("a")));
 
    // uses pair's converting move constructor
    m.emplace(std::make_pair("b", "abcd"));
 
    // uses pair's template constructor
    m.emplace("d", "ddd");
 
    // uses pair's piecewise constructor
    m.emplace(std::piecewise_construct,
              std::forward_as_tuple("c"),
              std::forward_as_tuple(10, 'c'));

emplace就是想在in-place的情况下construct a map::value_type,也就是一个pair类型。如上所示,只要不使用pecewise_construct和forward_as_tuple就是使用pair类型的move/convert move/template constructor。

If either the key or the value needs more than one constructor argument, you’ll need forward_as_tuple.    std::[unordered_]map takes its first two template parameters and feeds them into std::pair to generate its map::value_type.


先说结论,在使用empalce的过程中,如果使用make_pair(...),会需要使用pair中类型的move操作,但是如果使用piecewise_construct, forward_as_tuple, forward_as_tuple,就不需要move操作的支持。但是两种情况下都需要使用default constructor,这是tuple那边的需要。

size(), max_size(), max_bucket_count(), bucket_count(), bucket_size(size_type n)分别为number of elements, max number of elements, max number of buckets, number of buckets(就是当前已经有多少), number of elements in bucket n;自己写的hash table中就有bucket数目和elements数目的不同,这里可以按照字面意思理解了。其中前两个返回值在一个平台下面是固定的,bucket_count()的值随着加入元素个数的增加而变大来使得load factor低于max load factor。load_factor()返回一个float值表示当前的load factor= size()/bucket_count();max_load_factor()被重载,可以返回和设置最大装载系数,默认值为1.0。如果load_factor大于max_load_factor就会导致rehash(size_type n);rehash就是重设buckets的数目大于n或者更多,但是如果n < bucket_count(),可能不会对container造成任何影响。
rehash会导致所有的iterators失效,在load_factor > max_load_factor自动触发。这里rehash(size_type)的参数意义是buckets number, 而函数reserve(size_type n)的参数意义是设置buckets的数目来能装下n个elements即参数是elements的数目。函数bucket(const key_type& k)const返回k所对应的element所在bucket的数字。

想要遍历unordered_map就使用iterators,从begin()到end();或者 for (auto& x: mymap) {


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值