放置的两种方式:
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));
}第二: emplace with pair made std::make_pair
// 2.
{
std::string k2 = "key2";
std::string v2 = "value2";
m.emplace(std::make_pair(k2, v2));
}哪个更好(意味着更快更高效)?
发布于 2016-11-28 18:03:49
哪个更好?
如何做得更好?它们不是等价的。
示例1调用k1和v1的move构造函数,使它们处于有效但不同的状态,它们的内容将被移走。如果你打算在之后使用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个右值引用构造std::pair。
与
m.emplace(std::make_pair(std::move(k2), std::move(v2)));这调用了std::pair的move构造函数,因为它是一个右值。
如果是“哪个更好?”你的意思是性能,那么只有一种方法可以找到答案,那就是基准测试。虽然我认为m.emplace(std::move(k1), std::move(k2));有轻微的优势。(如注释中所述,因为它避免了从非常数到常量的转换)
要点,不用担心,它们都是非常有效的,因为它们都在移动。选择你认为可读性更好的那一个。
发布于 2016-11-28 18:25:28
第二种选择需要额外的移动/复制操作,这是不好的。第一个选项的运行速度更快,因为没有显式创建对。实际上,在显式创建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()
复制
移动
https://stackoverflow.com/questions/40841174
复制相似问题