boost :: unordered_map.emplace(Args && ... args)如何工作?

Man*_*rse 11 c++ boost unordered-map

根据文件它:

当且仅当容器中没有具有等效键的元素时,才在容器中插入使用参数args构造的对象.

但是,可以插入到unordered_map中的唯一对象具有类型 std::pair<Key const, Mapped>(因为要插入的对象需要键和值),这已知具有正好两个参数的构造函数.那么为什么它使用可变函数形式呢?当然,我完全不了解这一点.

whe*_*ies 8

对emplace_back对比的push_back SO文章.本质上,它允许从传递给它的参数构造对象,而无需首先创建要传递的对象.它通过删除通常由于创建要插入的对象而发生的复制结构来节省开销.

所以你可以逃脱这个:

unordered_map<int,int> foo;
foo.emplace(4, 5);
Run Code Online (Sandbox Code Playgroud)

代替

foo.insert(std::make_pair(4, 5));
Run Code Online (Sandbox Code Playgroud)

更好的,(如果我没有记错的话),你可以通过这条路线:

struct Bar{
    int x,y;
    Bar(int _x, int _y) : x(_x), y(_y){}
};

unordered_map<int,Bar> baz;
baz.emplace(4, 5, 6);
Run Code Online (Sandbox Code Playgroud)

并取自C++ 0x上的Wiki :

由于rvalue引用的措辞的性质,以及对左值引用(常规引用)的措辞的一些修改,rvalue引用允许开发人员提供完美的函数转发.当与可变参数模板结合使用时,此功能允许功能模板可以完美地将参数转发给另一个采用这些特定参数的函数.这对于转发构造函数参数,创建工厂函数非常有用,这些函数将自动为这些特定参数调用正确的构造函数.

其工作方式如下:

template<typename TypeToConstruct> struct SharedPtrAllocator {

    template<typename ...Args> std::shared_ptr<TypeToConstruct> construct_with_shared_ptr(Args&&... params) {
        return std::shared_ptr<TypeToConstruct>(new TypeToConstruct(std::forward<Args>(params)...));
    }
}
Run Code Online (Sandbox Code Playgroud)

再次,从上面提到的Wiki文章中无耻地窃取.


Aur*_*oms 5

既然C++标准库集成了Boost的那部分:

来自http://en.cppreference.com

#include <iostream>
#include <utility>
#include <tuple>

#include <unordered_map>

int main(){
    std::unordered_map<std::string, std::string> m;

    // uses pair's piecewise constructor
    m.emplace(std::piecewise_construct,
        std::forward_as_tuple("c"),
        std::forward_as_tuple(10, 'c'));

    for (const auto &p : m) {
        std::cout << p.first << " => " << p.second << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

std::piecewise_construct 是一个常量,不会对如何使用参数产生歧义

  • 第一个元组将用于构造密钥
  • 第二个构建价值