РЕДАКТИРОВАТЬ:
Из трех форм, обсуждаемых в этой теме, та, которая позволяет избежать ненужных копий, — это форма, предложенная @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
============
ОРИГИНАЛ (НЕПРАВИЛЬНО)
Я был немного ленив и не пытался копать глубже, прежде чем публиковать вопрос. Теперь я вижу, что все эти три формы (третья форма взята из комментария @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: я проверил, что каждая строка в приведенном выше выводе соответствует одному вызову emplace выше.
person
DigitalEye
schedule
04.08.2017
make_pair
использует семантику конструктора перемещенияpair
, тогда как другим способом вы вызываете конструктор шаблона. - person Swift - Friday Pie   schedule 03.08.2017fooMap.emplace(std::piecewise_construct, std::forward_as_tuple(0), std::forward_as_tuple(1, 2));
? - person max66   schedule 03.08.2017