NHDaly
Según las respuestas a estas preguntas aquí, sé que ciertamente se prefiere usar c ++ 14 std::make_unique
que a emplace_back(new X)
directamente.
Dicho esto, es preferible llamar
my_vector.push_back(std::make_unique<Foo>("constructor", "args"));
o
my_vector.emplace_back(std::make_unique<Foo>("constructor", "args"));
Es decir, ¿debería usar push_back
o emplace_back
al agregar un std::unique_ptr
construido a partir de std::make_unique
?
==== EDITAR ====
¿y por qué? c:
Pretoriano
No hace ninguna diferencia en lo que se refiere a la construcción del nuevo objeto; ya tienes un unique_ptr<Foo>
prvalue (el resultado de la llamada a make_unique
) por lo tanto push_back
y emplace_back
llamará al unique_ptr
mueva el constructor al construir el elemento que se agregará al vector
.
Si su caso de uso implica acceder al elemento recién construido después de la inserción, entonces emplace_back
es más conveniente desde C++17 porque devuelve una referencia al elemento. Entonces, en lugar de
my_vector.push_back(std::make_unique<Foo>("constructor", "args"));
my_vector.back().do_stuff();
puedes escribir
my_vector.emplace_back(std::make_unique<Foo>("constructor", "args")).do_stuff();
-
Si de acuerdo, por eso pregunto. 🙂
– NHDaly
17 de marzo de 2015 a las 1:15
-
En realidad, hay una diferencia…
emplace_back()
devuelve una referencia al elemento añadido, mientras quepush_back()
devuelve nula.emplace_back(std::make_unique<>())
por lo tanto, es útil en contextos en los que necesita usar el objeto después de haberlo agregado.– jb
19/09/2018 a las 18:40
-
@JamieBullock Bueno, no hubo diferencia cuando respondí la pregunta hace 3 años. Se actualizó la respuesta para incluir el cambio de C++ 17 al tipo de devolución. Gracias.
– Pretoriano
19/09/2018 a las 19:45
Yakk – Adam Nevraumont
Claramente
template<class T, class A, class...Args>
void push_unique( std::vector<std::unique_ptr<T>,A>& v, Args&&...args ) {
v.push_back( std::make_unique<T>(std::forward<Args>(args)...) );
}
es la mejor opción:
push_unique(my_vector,"constructor", "args");
lamentablemente, esta es la notación de prefijo: (operador, contenedor, argumentos…) vs infijo (argumentos de operador de contenedor…).
Si tan solo hubiera una manera de hacerlo infijo, como métodos de extensión o operadores con nombre.
Porque eso sería genial.
Con un argumento real del tipo de elemento del vector,
push_back
yemplace_back
necesariamente hacer lo mismo.– Saludos y hth. – alf
17 de marzo de 2015 a las 0:21
Relacionado: htmlpreview.github.io/?https://github.com/HowardHinnant/papers/…
– mojar
17 de marzo de 2015 a las 0:21
@Praetorian, gracias.
– NHDaly
17 de marzo de 2015 a las 0:24
Si tiene un eliminador personalizado en su
unique_ptr
entonces las cosas pueden cambiar.– Yakk – Adam Nevraumont
17 de marzo de 2015 a las 0:59
Con respecto al enlace de @dyp, ejecuté ese código en VS2022 e insertar y colocar fueron idénticos en cada caso.
– Tomás
8 dic 2022 a las 18:32