dev compiler c++ c++11

c++ - compiler - ¿Por qué se llama al constructor de copia en call a std:: vector:: emplace_back()?



c++14 (1)

Tengo entendido que el propósito de std::vector::emplace_back() es específicamente evitar llamar a un constructor de copia, y en su lugar construir el objeto directamente.

Considere el siguiente código:

#include <memory> #include <vector> #include <boost/filesystem.hpp> using namespace std; struct stuff { unique_ptr<int> dummy_ptr; boost::filesystem::path dummy_path; stuff(unique_ptr<int> && dummy_ptr_, boost::filesystem::path const & dummy_path_) : dummy_ptr(std::move(dummy_ptr_)) , dummy_path(dummy_path_) {} }; int main(int argc, const char * argv[]) { vector<stuff> myvec; // Do not pass an object of type "stuff" to the "emplace_back()" function. // ... Instead, pass **arguments** that would be passed // ... to "stuff"''s constructor, // ... and expect the "stuff" object to be constructed directly in-place, // ... using the constructor that takes those arguments myvec.emplace_back(unique_ptr<int>(new int(12)), boost::filesystem::path()); }

Por alguna razón, a pesar del uso de la función emplace_back() , este código no se compila, con el error:

error C2248: ''std::unique_ptr<_Ty>::unique_ptr'' : cannot access private member declared in class ''std::unique_ptr<_Ty>'' [...] This diagnostic occurred in the compiler generated function ''stuff::stuff(const stuff &)''

Observe que el compilador intentó crear (y usar) el COPY CONSTRUCTOR . Como lo emplace_back() anteriormente, entiendo que el propósito de emplace_back() es evitar el uso del constructor de copia.

Por supuesto, dado que el compilador está intentando crear y llamar al constructor de copia , no hay forma de que el código se compile incluso si definiera el constructor de copia para stuff , porque std::unique_ptr no puede usarse en un constructor de copia. Por lo tanto, me gustaría mucho evitar el uso de un constructor de copias (de hecho, necesito evitarlo).

(Esto es VS 11.0.60610.01 Actualización 3 en Windows 7 de 64 bits)

¿Por qué el compilador genera e intenta usar el constructor de copia, aunque estoy llamando a emplace_back() ?

Nota (en respuesta a la respuesta de @Kakk):

Agregar explícitamente el constructor de movimiento, de la siguiente manera, resuelve el problema:

stuff(stuff && rhs) : dummy_ptr(std::move(rhs.dummy_ptr)) , dummy_path(rhs.dummy_path) {}


Visual Studio 2013 y versiones anteriores no pueden escribir los constructores de movimiento predeterminados por usted. Agregar un constructor de movimiento explícito simple a stuff .

Un empuje o emplazamiento hacia atrás puede hacer que las cosas se muevan si es necesario reasignarlas, lo que en su caso se copia, ya que las stuff no tienen movimiento.

Es un error de msvc.