编辑:
在此线程讨论的三种形式,即避免了不必要的拷贝之一是通过@ max66提出的形式。下面的代码,并且其输出捕获动作这三种形式
#include <iostream>
#include <map>
using namespace std;
struct FooStruct
{
FooStruct()
{
cout << "FooStruct Default Constructor" << endl;
}
FooStruct(const FooStruct& other)
{
this->a = other.a;
this->b = other.b;
cout << "FooStruct Copy Constructor" << endl;
}
FooStruct(int a, int b)
{
this->a = a;
this->b = b;
cout << "FooStruct Parametrized Constructor" << endl;
}
int a;
int b;
};
输出:
foo.emplace<int, FooStruct>(0, {1, 2})
FooStruct Parametrized Constructor
FooStruct Copy Constructor
fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }))
FooStruct Parametrized Constructor
FooStruct Copy Constructor
FooStruct Copy Constructor
fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4))
FooStruct Parametrized Constructor
============
ORIGINAL(WRONG)
我很懒惰,在发布问题前没有深入挖掘。我现在看到所有这三种形式(第三种形式来自@ max66的评论)是相同的,因为他们三个都避免了创建临时副本FooStruct
。
#include <iostream>
#include <map>
using namespace std;
struct FooStruct
{
FooStruct() { cout << "FooStruct Default Constructor" << endl; }
FooStruct(int a, int b) { this->a = a; this->b = b; cout << "FooStruct Parametrized Constructor" << endl; }
int a;
int b;
};
int main()
{
map<int, FooStruct> fooMap;
fooMap.emplace<int, FooStruct>(0, {1, 2});
fooMap.emplace(make_pair<int, FooStruct>(1, { 2, 3 }));
fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(2), std::forward_as_tuple(2, 4));
return 0;
}
上面的代码(用Visual C++ 2015内置)产生以下输出:
FooStruct Parametrized Constructor
FooStruct Parametrized Constructor
FooStruct Parametrized Constructor
PS:我没有验证,在上述输出的每一行对应于一个单一布设呼叫以上
区别在于'make_pair'使用'pair'的移动构造函数语义,而另一种方式是调用模板的构造函数。 – Swift
fooMap.emplace(std :: piecewise_construct,std :: forward_as_tuple(0),std :: forward_as_tuple(1,2));'? – max66
@ max66:你是说你的表单比上面提到的两个更好吗?如果是这样,你能解释为什么是这样吗? – DigitalEye