considerar:¿Debo std :: mover un shared_ptr en un constructor de movimiento?
#include <cstdlib>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class Gizmo
{
public:
Gizmo() : foo_(shared_ptr<string>(new string("bar"))) {};
Gizmo(Gizmo&& rhs); // Implemented Below
private:
shared_ptr<string> foo_;
};
/*
// doesn't use std::move
Gizmo::Gizmo(Gizmo&& rhs)
: foo_(rhs.foo_)
{
}
*/
// Does use std::move
Gizmo::Gizmo(Gizmo&& rhs)
: foo_(std::move(rhs.foo_))
{
}
int main()
{
typedef vector<Gizmo> Gizmos;
Gizmos gizmos;
generate_n(back_inserter(gizmos), 10000, []() -> Gizmo
{
Gizmo ret;
return ret;
});
random_shuffle(gizmos.begin(), gizmos.end());
}
En el código anterior, hay dos versiones de Gizmo::Gizmo(Gizmo&&)
- uno utiliza a std::move
realidad movimiento la shared_ptr
, y el otro sólo copia el shared_ptr
.
Ambas versiones parecen funcionar en la superficie. Una diferencia (la única diferencia que puedo ver) es en la versión no move
, el recuento de referencia del shared_ptr
se incrementa temporalmente, pero solo brevemente.
Normalmente seguiría adelante y move
el shared_ptr
, pero solo para ser claro y consistente en mi código. ¿Me estoy perdiendo una consideración aquí? ¿Debo preferir una versión sobre la otra para cualquier razón técnica?
Mover en un constructor de movimientos es al menos semánticamente consistente ... – ildjarn
¿Por qué mantienes la cadena en un shared_ptr? Un shared_ptr como miembro-variable es a menudo un signo de mal diseño. –
Mover en un constructor de movimientos está en línea con lo que el compilador generaría automáticamente. –