两种放置方式:
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));
}
哪个更好(意味着速度更快)?
答案 0 :(得分:2)
哪个更好?
更好的方法?它们并不等同。
示例1调用k1
和v1
的移动构造函数,使它们处于有效但不同的状态,它们的内容将被移走。如果您打算之后使用k1
或v1
则没有选项,您应该使用#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()
复制
移动