【问题标题】:Emplacing a std::pair放置一个 std::pair
【发布时间】:2014-09-10 13:27:35
【问题描述】:

有没有办法设置std::pair

std::unordered_map<int, std::pair<std::string, std::string>> my_map;
my_map.emplace(1, "foo", "bar"); // Error

当然可以插入:

my_map[2] = std::make_pair("bar", "foo");

但这不需要不必要的复制/移动吗?

【问题讨论】:

    标签: c++ c++11 stl


    【解决方案1】:

    有没有办法放置一个 std::pair?

    参数需要适合pair&lt;int, pair&lt;string,string&gt;&gt;的构造函数,映射的value_type

    my_map.emplace(1, std::make_pair("foo", "bar"));
    

    但这不需要不必要的复制/移动吗?

    没有; make_pair 生成一对指向字符串文字的指针,然后用于初始化(在emplace 的情况下)或分配给(在[] 的情况下)映射中包含的字符串。

    【讨论】:

    • 对此进行扩展 - emplace 不会创建对象然后将其移动到容器中;它使用 forwarding 将参数转发给容器,然后一旦容器确定了它希望在内存中构造对象的位置,容器就会调用对象构造函数。 (误导性的函数名称!)
    【解决方案2】:

    在这种情况下,放置“值类型”std::pair 的部分意义不大,因为std::string 既可以有效地从 C 字符串转换,也可以有效地移动到地图中。简单的m.emplace( 3, std::make_pair( "bob", "alice" ) ),您就可以达到最佳效率的 99%。

    但是,如果您有一个映射到无法以这种方式有效构造的类型的 std::map,则 C++11 会为 std::pair 提供 std::piecewise_constructemplaced。

    struct A { }; // nothing
    struct C { C(C&&)=delete; }; // no copy/move
    struct B { B()=delete; B(B&&)=delete; B(C&&, C&&) {}; }; // no copy/move, only annoying ctor
    
    std::map< int, std::pair<A,B> > test;
    // test.emplace( 0, std::make_pair( A{}, B{} ); // does not compile
    // test.emplace( 0, std::make_pair( A{}, B{C{},C{}} ); // does not compile
    test.emplace( std::piecewise_construct,
      std::make_tuple(0),
      std::forward_as_tuple(
        std::piecewise_construct,
        std::forward_as_tuple(A{}),
        std::forward_as_tuple( C{}, C{} )
      )
    ); // compiles!
    

    live example

    这是一个极端的极端情况,因为高效移动的对象更为常见。

    【讨论】:

    • 呃。 std::piecewise_construct 是 C++11,而不是 C++14。
    【解决方案3】:

    是的,有:

    my_map.emplace(1, std::make_pair("foo", "bar"));
    

    【讨论】:

      【解决方案4】:

      对于 C++17,您可以使用 try_emplace

      std::unordered_map<int, std::pair<std::string, std::string>> my_map;
      my_map.try_emplace(1, "foo", "bar");
      

      【讨论】:

        猜你喜欢
        • 2011-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-29
        • 1970-01-01
        • 2012-08-14
        • 1970-01-01
        • 2013-08-18
        相关资源
        最近更新 更多