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?