c ++-从初始化列表中初始化unique_ptrs的容器在GCC 4.7中失败

我正在尝试以与Bjarne Stroustrup的C ++ 11 FAQ中的示例等效的方式初始化'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

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

我看不出为什么该语法会失败。 这种初始化容器的方式有什么问题吗?
编译器错误消息很大; 我找到的相关细分如下:

/usr/lib/gcc-snapshot/lib/gcc/i686-linux-gnu/4.7.0/../../../../include/c++/4.7.0   /bits/stl_construct.h:77:7:错误:没有匹配的函数可以调用   'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

解决此错误的方法是什么?

2个解决方案
61 votes

string的构造函数为vector<string>。因此,您不能使用std::string隐式创建一个构造函数。它必须类似于unique_ptr<string>{ new string{"foo"} }

这导致我们这样做

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

但是,如果其中一个构造函数失败,则可能会泄漏。 使用string更安全:

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

但是... strings始终执行副本,而vector<string>s不可复制。 这对于初始化列表确实很烦人。 您可以修改它,也可以回退到调用std::string的初始化。

如果您实际上是在使用智能指针管理strings,而不仅仅是作为示例,那么您甚至可以做得更好:只需制作vector<string>std::string已经可以处理它使用的资源。

R. Martinho Fernandes answered 2020-01-22T06:55:42Z
3 votes

在“修复”您的示例之后:

#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
}

我得到了非常清楚的错误消息:

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>*]'

此错误表明无法使用271352103752171616224的显式构造函数。

BЈовић answered 2020-01-22T06:56:11Z
translate from https://stackoverflow.com:/questions/9618268/initializing-container-of-unique-ptrs-from-initializer-list-fails-with-gcc-4-7