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

标签 c++ compiler-errors initialization c++11

我正在尝试初始化 std::vector<std::unique_ptr<std::string>>以相当于 Bjarne Stroustrup's C++11 FAQ 中的示例的方式:

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: error: no matching function for call to 'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

解决这个错误的方法是什么?

最佳答案

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 不可复制。这对于初始化列表来说真的很烦人。您可以hack around it , 或通过调用 emplace_back 回退到初始化.

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

关于c++ - GCC 4.7 从初始化器列表初始化 unique_ptrs 容器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9618268/

相关文章:

c - 使用函数指针的静态结构初始化

c++ - 正确终止程序。使用异常

c++ - 使用 MinGW 构建 ASSIMP 会导致文件太大错误

c++ - Qt重构QStandardItemModel

c++ - ProjectName.exe已触发断点

java - 高效的对象初始化

C++:POD 类型可以包含 const 非指针成员吗?

c++ - C++中的核心头文件

ubuntu - nvcc 致命 : Unsupported gpu architecture 'compute_86'

javascript - 如何通过索引分配 Javascript 数组