Debe informar a C ++ (específicamente std::vector
) que su constructor de movimiento y su destructor no arroja, usando noexcept
. Luego, se llamará al constructor de movimiento cuando el vector crezca.
Así es como declarar e implementar un constructor de movimiento que es respetado por 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) ;
}
Si el constructor no lo es noexcept
, no std::vector
puede usarlo, ya que entonces no puede asegurar las garantías de excepción exigidas por el estándar.
Para obtener más información sobre lo que se dice en el estándar, lea
C ++ Move semántica y excepciones
Gracias a Bo, quien insinuó que puede tener que ver con excepciones. También considere los consejos de Kerrek SB y utilícelo emplace_back
cuando sea posible. Se puede ser más rápido (pero a menudo no lo es), que puede ser más clara y compacta, pero también hay algunas trampas (especialmente con los constructores no explícitas).
Edite , a menudo lo predeterminado es lo que desea: mueva todo lo que se pueda mover, copie el resto. Para pedirlo explícitamente, escriba
A(A && rhs) = default;
Al hacer eso, obtendrá noexcepto cuando sea posible: ¿El constructor Move predeterminado está definido como noexcept?
Tenga en cuenta que las versiones anteriores de Visual Studio 2015 y anteriores no lo admitían, aunque admite la semántica de movimiento.