GCC 4.7 从初始化器列表初始化 unique_ptrs 容器失败

新手上路,请多包涵

我正在尝试以与 Bjarne Stroustrup 的 C++11 FAQ 中的示例等效的方式初始化 std::vector<std::unique_ptr<std::string>>

 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>&)'

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

原文由 juanchopanza 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 592
2 个回答

unique_ptr 的构造函数是 explicit 。因此,您不能使用 from new string{"foo"} 隐式创建一个。它需要类似于 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"} }
};

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

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

但是… initializer_list s 总是执行复制,而 unique_ptr s 是不可复制的。这对于初始化列表来说真的很烦人。您可以 绕过它,或者通过调用 emplace_back 回退到初始化。

如果您实际上正在使用智能指针管理 string s,并且不仅仅是示例,那么您可以做得更好:只需制作一个 vector<string>std::string 已经处理了它使用的资源。

原文由 R. Martinho Fernandes 发布,翻译遵循 CC BY-SA 4.0 许可协议

在“修复”你的例子之后:

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

这个错误告诉我们不能使用 unique_ptr 的显式构造函数!

原文由 BЈовић 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题