c ++ 11 emplace_back und push_back syntax mit struct

Ich verwende MSVC, Visual Studio 2013.

Angenommen, ich habe eine Struktur:

struct my_pair {
    int foo, bar;
};

Und ich möchte ein paar davon effizient hinzufügen, ohne ein temporäres zu erstellen und es dann zu verwerfen:

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]

Nun, wenn ich einen Konstruktor und einen Kopierkonstruktor zu meinem Code hinzufüge:

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;
}

Dann ändert sich das Verhalten:

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]

Wenn ich einen Verschiebungskonstruktor hinzufüge:

my_pair(my_pair&& move_) : foo(move_.foo), bar(move_.bar)
{
    cout << "in move cstor" << endl;
}

Dann:

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]

Fragen:
zum[a, b] Ich verstehe den Grund zu arbeiten und nicht zu arbeiten.
zum[c]funktioniert nicht, da es keinen Konstruktor gibt, an den die Argumente weitergeleitet werden können.
zum[d], warum funktioniert das nicht so wie im Push-Fall?
zum[e]Warum funktioniert es, wenn der Klassenname hinzugefügt wird?
zum[h]Dies scheint der effizienteste Code zu sein, wenn es einen Konstruktor gibt, der die Argumente den Mitgliedern zuordnet
zum[j]Es sieht so aus, als wäre dies so schlimm wie ein push_back und mit zusätzlicher Eingabe bin ich mir nicht sicher, warum jemand dies über push_back tun sollte
zum[k, m]Mit der Hinzufügung eines Verschiebungskonstruktors scheint es sopush_back(T&&) wird aufgerufen, was zu der gleichen Leistung wie emplace führt. Aber mit der zusätzlichen Eingabe bin ich mir nicht sicher, warum das jemand tun würde.

Ich habe gelesen, dass MSVC keinen Verschiebungskonstruktor für Sie hinzufügt:Warum wird der Kopierkonstruktor beim Aufruf von std :: vector :: emplace_back () aufgerufen?

Was ist der Unterschied zwischen[d, e] und warum ist emplace wählerisch. Und warum?push_back(T&&) Ohne den Namen der Struktur arbeiten?

Ich kann die Vorteile von emplace nur dann voll ausschöpfen, wenn ich weiß, dass es einen Konstruktor gibt, der jedes Mitglied als Argument verwendet.

Soll ich einfach bleibenpush_back? Gibt es einen Grund zur Verwendungemplace_back(structname{1,2,3}) anstattpush_back({1,2,3}) weil es am Ende anrufen wirdpush_back(T&&) sowieso, und ist einfacher zu tippen?

Drittens, wie geht das?emplace_back(arg1,arg2,etc), ist es magisch, den Kopier- oder Verschiebekonstruktor komplett zu meiden?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage