Sí, pero no. Su código sólo debe ser la siguiente:
struct X
{
Y y_;
X(Y y) : // either copy, move, or elide a Y
y_(std::move(y)) // and move it to the member
{}
};
Si alguna vez se dice en el diseño "Necesito mi propia copia de estos datos" *, a continuación, sólo debe tomar el argumento de valor y moverlo a donde tiene que estar . No es su trabajo decidir cómo construir ese valor, eso depende de los constructores disponibles para ese valor, así que déjelo hacer esa elección, sea lo que sea, y trabaje con el resultado final.
* Esto se aplica a funciones también, por supuesto, por ejemplo:
void add_to_map(std::string x, int y) // either copy, move or elide a std::string
{
// and move it to where it needs to be
someMap.insert(std::make_pair(std::move(x), y));
}
Nota que se aplica en C++ 03 también, en cierta medida, si era un tipo construible defecto y intercambiables (que todo se mueve de todos modos):
// C++03
struct X
{
std::string y_;
X(std::string y) // either copy or elide a std::string
{
swap(y_, y); // and "move" it to the member
}
};
Aunque esto no parece ser tan ampliamente hecho.
Un generador de movimiento u operador de asignación se genera implícitamente [en ciertas circunstancias] (http://stackoverflow.com/questions/4819936/why-no-default-move-assignment-move-constructor/4820339#4820339). Como ha declarado un constructor de copias aquí, también deberá declarar y definir un constructor de movimientos apropiado usted mismo. Sin embargo, puede eliminar ambos y tener el mismo comportamiento en su caso específico. –
@James: información útil. Sin embargo, no definí un constructor de copia aquí. Definí un constructor de Y a X. –
Oh. Lo siento, solo vi cartas y pensé que eran todas iguales. –