c++ compiler-errors initialization c++11

c++ - El contenedor de inicialización de unique_ptrs de la lista de inicializadores falla con GCC 4.7



compiler-errors initialization (2)

Después de "arreglar" tu ejemplo:

#include <vector> #include <memory> #include <string> int main() { std::vector<std::unique_ptr<std::string>> vs = { { new std::string{"Doug"} }, { new std::string{"Adams"} } }; // fails std::unique_ptr<std::string> ps { new std::string{"42"} }; // OK }

Tengo un mensaje de error muy claro:

error: converting to ''std::unique_ptr<std::basic_string<char> >'' from initializer list would use explicit constructor ''std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = std::basic_string<char>, _Dp = std::default_delete<std::basic_string<char> >, std::unique_ptr<_Tp, _Dp>::pointer = std::basic_string<char>*]''

Este error indica que no es posible utilizar el contructor explícito de unique_ptr .

Estoy tratando de inicializar un std::vector<std::unique_ptr<std::string>> de una manera que es equivalente a un ejemplo de C ++ 11 de Bjarne Stroustrup :

using namespace std; vector<unique_ptr<string>> vs { new string{"Doug"}, new string{"Adams"} }; // fails unique_ptr<string> ps { new string{"42"} }; // OK

No veo ninguna razón por la que esta sintaxis deba fallar. ¿Hay algo malo con esta forma de inicializar el contenedor?
El mensaje de error del compilador es enorme; El segmento relevante que encuentro está abajo:

/usr/lib/gcc-snapshot/lib/gcc/i686-linux-gnu/4.7.0/../../../../include/c++/4.7.0 /bits/stl_construct.h:77 : 7: error: no hay función coincidente para la llamada a ''std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)''

¿Cuál es la manera de solucionar este error?


El constructor de unique_ptr es explicit . Entonces no puedes crear uno implícitamente con una new string{"foo"} . Debe ser algo como unique_ptr<string>{ new string{"foo"} } .

Lo que nos lleva a esto.

// not good vector<unique_ptr<string>> vs { unique_ptr<string>{ new string{"Doug"} }, unique_ptr<string>{ new string{"Adams"} } };

Sin embargo, puede filtrarse si falla uno de los constructores. Es más seguro usar make_unique :

// does not work vector<unique_ptr<string>> vs { make_unique<string>("Doug"), make_unique<string>("Adams") };

Pero ... initializer_list s siempre realiza copias, y unique_ptr s no son copiables. Esto es algo realmente molesto acerca de las listas de inicialización. Puede hackearlo o retroceder a la inicialización con llamadas a emplace_back .

Si realmente está administrando string con punteros inteligentes y no es solo para el ejemplo, puede hacerlo aún mejor: simplemente haga un vector<string> . La std::string ya maneja los recursos que usa.