emplace(std :: move(key),std :: move(value))vs emplace(std :: make_pair(key,value))

时间:2016-11-28 09:41:22

标签: c++

两种放置方式:

std::unordered_map<std::string, std::string> m;

首先:移动键移动键和值

// 1.
{
    std::string k1 = "key1";
    std::string v1 = "value1";
    m.emplace(std::move(k1), std::move(v1));
}

第二:使用对子进行std::make_pair

// 2.
{
    std::string k2 = "key2";
    std::string v2 = "value2";
    m.emplace(std::make_pair(k2, v2));
}

哪个更好(意味着速度更快)?

2 个答案:

答案 0 :(得分:2)

  

哪个更好?

更好的方法?它们并不等同。

示例1调用k1v1的移动构造函数,使它们处于有效但不同的状态,它们的内容将被移走。如果您打算之后使用k1v1则没有选项,您应该使用#2。如果你不这样做,那么你也应该进入#2以避免副本:

m.emplace(std::make_pair(std::move(k2), std::move(v2)));

然后将其留给可读性:

m.emplace(std::move(k1), std::move(k2));

这会调用std::pair的模板构造函数从2个右值refs构造std::pair

<强> VS

m.emplace(std::make_pair(std::move(k2), std::move(v2)));

这会调用std::pair的移动构造函数,因为它是一个右值。

如果“哪个更好?”你的意思是表现那么只有一种方法可以找到,这就是基准测试。虽然我认为m.emplace(std::move(k1), std::move(k2));略有优势。 (如评论中所述,因为它避免了从非const到const的转换)

要点,不要出汗,两者都会非常有效,因为它们都在移动。选择你认为更具可读性的那个。

答案 1 :(得分:0)

第二个选项需要额外的移动/复制操作,这不是好事。第一个选项工作得更快,因为没有明确的对创建。实际上,通过明确创建std::pair来插入和放置会给你相同的速度 我测试过了。 std::make_pair选项需要3次调用键/值的移动构造函数,std::move的选项只需要调用1次移动构造函数。 没有和带有/ Ox优化的示例。 MSVC-2012

class C
{
    public:
    C()
    {
       std::cout << "C()" << std::endl;
    }

    C( const C& c )
    {
       std::cout << "copy" << std::endl;
    }

    C( C&& c )
    {
       std::cout << "move" << std::endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::unordered_map<int, C> c1;

    std::cout << "---Test Move---" << std::endl;
    C test1;
    c1.emplace(1, std::move(test1));

    std::cout << "---Test std::make_pair---" << std::endl;
    C test2;
    c1.emplace(std::make_pair(2, test2) );

    std::cout << "---Test bare pair---" << std::endl;
    C test3;
    c1.emplace(std::pair<const int, C>(3, test3) );

    return 0;
}

---测试移动---
C()
移动
---测试std :: make_pair ---
C()
复制
移动
移动
---测试裸对---
C()
复制
移动