c ++ 11 Składnia emplace_back i push_back ze strukturą

Używam MSVC, Visual Studio 2013.

Załóżmy, że mam strukturę:

struct my_pair {
    int foo, bar;
};

I chcę skutecznie dodać kilka takich, bez tworzenia tymczasowego, a następnie odrzucenia:

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]

Jeśli dodam konstruktor i konstruktor kopii do mojego kodu:

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

Następnie zachowanie się zmienia:

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]

Jeśli dodam konstruktora ruchu:

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

Następnie:

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]

Pytania:
dla[a, b] Rozumiem powód pracy i nie działa.
dla[do], nie działa, ponieważ nie ma konstruktora do przekazania argumentów.
dla[re], dlaczego to nie działa jak w walizce?
dla[mi], dlaczego działa, gdy dodana jest nazwa klasy?
dla[h]wygląda na to, że jest to najbardziej wydajny kod, jeśli istnieje konstruktor odwzorowujący argumenty na członków
dla[jot], wygląda na to, że jest to tak samo złe jak push_back iz dodatkowym typowaniem Nie jestem pewien, dlaczego ktoś powinien to zrobić przez push_back
dla[k, m], wydaje się, że z dodatkiem konstruktora ruchupush_back(T&&) jest wywoływane, co daje taką samą wydajność jak stanowisko. Ale znowu, z dodatkowym typowaniem, nie jestem pewien, dlaczego ktoś to zrobił.

Czytałem, że MSVC nie dodaje dla ciebie konstruktora ruchu:Dlaczego konstruktor kopiowania został wywołany w wywołaniu std :: vector :: emplace_back ()?

Jaka jest różnica pomiędzy[d, e] i dlaczego jest to wybredne. I dlaczegopush_back(T&&) działa bez dodawania nazwy struktury?

Mogę uzyskać pełne korzyści ze stanowiska, jeśli wiem, że istnieje konstruktor, który bierze każdego członka jako argument?

Powinienem się po prostu trzymaćpush_back? Czy jest jakiś powód do użyciaemplace_back(structname{1,2,3}) zamiastpush_back({1,2,3}) ponieważ to skończy się dzwonićpush_back(T&&) w każdym razie i łatwiej jest pisać?

Po trzecie, jak to zrobićemplace_back(arg1,arg2,etc), zrób swoją magię, aby całkowicie uniknąć konstruktora kopiowania lub przenoszenia?

questionAnswers(1)

yourAnswerToTheQuestion