編輯:
在此線程討論的三種形式,即避免了不必要的拷貝之一是通過@ 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