c ++ 11 синтаксис emplace_back и push_back со структурой
Я использую MSVC, Visual Studio 2013.
Предположим, у меня есть структура:
struct my_pair {
int foo, bar;
};
И я хочу добавить кучу из них эффективно, не создавая временные и не удаляя их:
vector<my_pair> v;
v.push_back(41, 42); // does not work [a]
v.push_back({41,42}); // works [b]
v.emplace_back(41,42); // does not work [c]
v.emplace_back({41,42}); // does not work [d]
v.emplace_back(my_pair{41,42}); //works [e]
Теперь, если я добавлю конструктор и скопирую конструктор в мой код:
my_pair(int foo_, int bar_) : foo(foo_), bar(bar_)
{
cout << "in cstor" << endl;
}
my_pair(const my_pair& copy) : foo(copy.foo), bar(copy.bar)
{
cout << "in copy cstor" << endl;
}
Затем поведение меняется:
v.push_back(41, 42); // does not work [f]
v.push_back({41,42}); // displays "in cstor" and "in copy cstor" [g]
v.emplace_back(41,42); // displays "in cstor" [h]
v.emplace_back({41,42}); // does not work [i]
v.emplace_back(my_pair{41,42}); // "in cstor" and "in copy cstor" [j]
Если я добавлю конструктор перемещения:
my_pair(my_pair&& move_) : foo(move_.foo), bar(move_.bar)
{
cout << "in move cstor" << endl;
}
Затем:
v.emplace_back(my_pair{41,42}); //displays "in cstor", "in move cstor" [k]
v.emplace_back({41,42}); // still does not work [l]
v.push_back({41,42}); // displays "in cstor", "in move cstor" [m]
Вопросов:
за[А, Ь] Я понимаю причину работы и не работает.
за[С], это не работает, потому что нет конструктора для пересылки аргументов.
за[D]почему это не работает как в случае push?
за[Е]Почему это работает, когда имя класса добавляется?
за[час]кажется, что это самый эффективный код, если есть конструктор, который отображает аргументы в члены
за[J]Похоже, что это так же плохо, как push_back и с дополнительным набором текста я не уверен, почему кто-то должен делать это по сравнению с push_back
за[К, т]с добавлением конструктора перемещения это выглядит какpush_back(T&&)
вызывается, что приводит к той же производительности, что и emplace. Но опять же, с дополнительным набором текста я не уверен, почему кто-то сделал бы это.
Я читал, что MSVC не добавляет конструктор перемещения для вас:Почему конструктор копирования вызывается при вызове std :: vector :: emplace_back ()?
В чем разница между[D, е] и почему emplace придирчив в этом. И почемуpush_back(T&&)
работать без добавления имени структуры?
Я могу получить все преимущества emplace, только если знаю, что существует конструктор, который принимает каждый член в качестве аргумента?
Должен ли я просто придерживатьсяpush_back
? Есть ли причина использоватьemplace_back(structname{1,2,3})
вместоpush_back({1,2,3})
потому что это в конечном итоге вызовpush_back(T&&)
во всяком случае, а проще набрать?
В-третьих, какemplace_back(arg1,arg2,etc)
, его магия, чтобы избежать копирования или полностью переместить конструктор?