De C++ 11 en adelante, todos los contenedores estándar (std::vector
, std::map
, etc) semántica de soporte se mueven, lo que significa que ahora puede pasar a rvalues contenedores estándar y evitar una copia:
// Example object class.
class object
{
private:
int m_val1;
std::string m_val2;
public:
// Constructor for object class.
object(int val1, std::string &&val2) :
m_val1(val1),
m_val2(std::move(val2))
{
}
};
std::vector<object> myList;
// #1 Copy into the vector.
object foo1(1, "foo");
myList.push_back(foo1);
// #2 Move into the vector (no copy).
object foo2(1024, "bar");
myList.push_back(std::move(foo2));
// #3 Move temporary into vector (no copy).
myList.push_back(object(453, "baz"));
// #4 Create instance of object directly inside the vector (no copy, no move).
myList.emplace_back(453, "qux");
alternativa, puede utilizar varios punteros inteligentes para conseguir su mayoría el mismo efecto:
std::unique_ptr
ejemplo
std::vector<std::unique_ptr<object>> myPtrList;
// #5a unique_ptr can only ever be moved.
auto pFoo = std::make_unique<object>(1, "foo");
myPtrList.push_back(std::move(pFoo));
// #5b unique_ptr can only ever be moved.
myPtrList.push_back(std::make_unique<object>(1, "foo"));
std::shared_ptr
ejemplo
std::vector<std::shared_ptr<object>> objectPtrList2;
// #6 shared_ptr can be used to retain a copy of the pointer and update both the vector
// value and the local copy simultaneously.
auto pFooShared = std::make_shared<object>(1, "foo");
objectPtrList2.push_back(pFooShared);
// Pointer to object stored in the vector, but pFooShared is still valid.
Este es un principio básico de C++. Los objetos son valores. La asignación hace una copia. No son posibles dos variables que hagan referencia al mismo objeto a menos que modifique el tipo con '*' o '&' para hacer un puntero o referencia. –
@DanielEarwicker push_back realmente toma una referencia. No está claro solo por la firma que hará una copia. –
@BrianGordon - ¡No lo dice! De ahí la necesidad del principio rector. Aún así, podemos deducir algo de la firma de 'push_back': toma' const & '. O arroja el valor (inútil), o hay un método de recuperación. Así que observamos la firma de 'back', y devuelve plain' & ', por lo que o bien se copió el valor original o se descartó silenciosamente el' const' (muy malo: comportamiento potencialmente indefinido). Asumiendo que los diseñadores de 'vector' eran racionales (' vector 'no obstante) concluimos que hace copias. –