Musisz poinformować C ++ (konkretnie std::vector
), że twój konstruktor przenoszenia i destruktor nie rzucają, używając noexcept
. Następnie konstruktor przenoszenia zostanie wywołany, gdy wektor wzrośnie.
Oto jak zadeklarować i zaimplementować konstruktor ruchu, który jest przestrzegany przez std::vector
:
A(A && rhs) noexcept {
std::cout << "i am the move constr" <<std::endl;
... some code doing the move ...
m_value=std::move(rhs.m_value) ;
}
Jeśli konstruktor nie jest noexcept
, std::vector
nie można go używać, ponieważ wtedy nie będzie w stanie zapewnić gwarancje wyjątków wymaganych przez normy.
Aby uzyskać więcej informacji na temat tego, co zostało powiedziane w standardzie, przeczytaj
semantykę ruchu i wyjątki w języku C ++
Podziękowania dla Bo, który zasugerował, że może to mieć związek z wyjątkami. Weź również pod uwagę rady Kerreka SB i użyj ich, emplace_back
jeśli to możliwe. To może być szybsze (ale często nie jest), to może być jaśniejszy i bardziej zwarta, ale jest też kilka pułapek (zwłaszcza bez wyraźnych konstruktorów).
Edytuj , często domyślnym jest to, czego chcesz: przenieś wszystko, co można przenieść, skopiuj resztę. Aby wyraźnie o to poprosić, napisz
A(A && rhs) = default;
Robiąc to, otrzymasz noexcept, jeśli to możliwe: Czy domyślny konstruktor Move jest zdefiniowany jako noexcept?
Należy pamiętać, że wczesne wersje programu Visual Studio 2015 i starsze nie obsługiwały tego, mimo że obsługuje semantykę przenoszenia.