unordered_map::emplace学习

先不说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) {


你可能感兴趣的:(unordered_map::emplace学习)