GCC 4.7 从初始化器列表初始化 unique_ptrs 容器失败
我正在尝试以与 Bjarne Stroustrup 的 C++11 常见问题解答:
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:错误:没有匹配的调用函数'std::unique_ptr
/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>&)'
解决这个错误的方法是什么?
What is the way to fix this error ?
推荐答案
unique_ptr
的构造函数是explicit
.所以你不能用 new string{"foo"}
隐式创建一个.它需要类似于 unique_ptr<string>{ new string{"foo"} }
.
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"} }
.
这导致我们这样做
// not good
vector<unique_ptr<string>> vs {
unique_ptr<string>{ new string{"Doug"} },
unique_ptr<string>{ new string{"Adams"} }
};
但是,如果其中一个构造函数失败,它可能会泄漏.使用 make_unique
更安全:
However it may leak if one of the constructors fails. It's safer to use make_unique
:
// does not work
vector<unique_ptr<string>> vs {
make_unique<string>("Doug"),
make_unique<string>("Adams")
};
但是... initializer_list
总是执行复制,而 unique_ptr
是不可复制的.这对于初始化列表来说真的很烦人.您可以破解它,或者通过调用emplace_back
回退到初始化.
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
.
如果您实际上是在使用智能指针管理 string
并且不仅仅是为了示例,那么您可以做得更好:只需创建一个 vector
.std::string
已经处理了它使用的资源.
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.
相关文章