C++ 使用 GCC 4.7 从初始化列表初始化 unique_ptrs 的容器失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9618268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initializing container of unique_ptrs from initializer list fails with GCC 4.7
提问by juanchopanza
I am trying to initialise an std::vector<std::unique_ptr<std::string>>
in a way that is equivalent to an example from Bjarne Stroustrup's C++11 FAQ:
我正在尝试以std::vector<std::unique_ptr<std::string>>
与Bjarne Stroustrup 的 C++11 FAQ 中的示例等效的方式初始化 an :
using namespace std;
vector<unique_ptr<string>> vs { new string{"Doug"}, new string{"Adams"} }; // fails
unique_ptr<string> ps { new string{"42"} }; // OK
I can see no reason why this syntax should fail. Is there something wrong with this way of initializing the container?
The compiler error message is huge; the relevant segment I find is below:
我看不出为什么这种语法会失败。这种初始化容器的方式有什么问题吗?
编译器错误信息很大;我找到的相关部分如下:
/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 matching function for call to
'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'
/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>&)'
What is the way to fix this error ?
修复此错误的方法是什么?
回答by R. Martinho Fernandes
unique_ptr
's constructor is explicit
. So you can't create one implicitly with from new string{"foo"}
. It needs to be something like unique_ptr<string>{ new string{"foo"} }
.
unique_ptr
的构造函数是explicit
. 所以你不能用 from 隐式地创建一个new string{"foo"}
。它需要类似于unique_ptr<string>{ new string{"foo"} }
.
Which leads us to this
这导致我们这样做
// not good
vector<unique_ptr<string>> vs {
unique_ptr<string>{ new string{"Doug"} },
unique_ptr<string>{ new string{"Adams"} }
};
However it may leak if one of the constructors fails. It's safer to use make_unique
:
但是,如果其中一个构造函数失败,它可能会泄漏。使用更安全make_unique
:
// does not work
vector<unique_ptr<string>> vs {
make_unique<string>("Doug"),
make_unique<string>("Adams")
};
But... initializer_list
s always perform copies, and unique_ptr
s are not copyable. This is something really annoying about initializer lists. You can hack around it, or fallback to initialization with calls to emplace_back
.
但是... initializer_list
s 总是执行复制,而unique_ptr
s 是不可复制的。这对于初始化列表来说真的很烦人。您可以绕过它,或者通过调用emplace_back
.
If you're actually managing string
s with smart pointers and it's not just for the example, then you can do even better: just make a vector<string>
. The std::string
already handles the resources it uses.
如果您实际上string
使用智能指针管理s 并且不仅仅是示例,那么您可以做得更好:只需创建一个vector<string>
. 在std::string
已经处理了它使用的资源。
回答by B?ови?
After "fixing" your example:
在“修复”您的示例之后:
#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
}
I got very a clear error message:
我收到了非常明确的错误消息:
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>*]'
This error tells us that it is not possible to use the unique_ptr
's explicit contructor!
这个错误告诉我们不可能使用unique_ptr
的显式构造函数!