考虑下面的代码:问题努力构建'的std :: VECTOR`与初始化列表
#include <memory>
#include <vector>
class A {
public:
explicit A(std::vector<int> &&v) : v_(std::move(v)) {}
private:
std::vector<int> v_;
};
int main() {
// compilation error (no matching call to std::make_unique)
// compiler output: https://ideone.com/4oKjCS
std::vector<std::unique_ptr<A>> as1 = {std::make_unique<A>({1}),
std::make_unique<A>({2})};
// compilation error (requested copy of std::unique_ptr)
// compiler output: https://ideone.com/5LGPoa
std::vector<std::unique_ptr<A>> as2 = {
std::make_unique<A>(std::vector<int>({1})),
std::make_unique<A>(std::vector<int>({2}))};
// succeeds
std::vector<std::unique_ptr<A>> as3;
as3.push_back(std::make_unique<A>(std::vector<int>({1})));
as3.push_back(std::make_unique<A>(std::vector<int>({2})));
}
- 对于
as1
:我希望std::make_unique<A>({1})
调用std::vector
隐含的初始化列表构造,然后传递矢量到std::make_unique
。为什么不编译? - 对于
as2
:std::make_unique
的结果是一个右值。为什么要在任何地方提交副本? - 有没有比我的
as3
更有地道或更短的方式来完成这项工作?
编辑:我现在记得as1
中的错误原因。 Meyers'Effective Modern C++在第30条中提到了初始值设定项列表作为完美转发的失败情况之一:“将标准初始化程序传递给函数模板参数(未声明为std::initializer_list
)被规定为,如标准所示,“未推断的上下文”。“
“int”的例子在任何情况下都可以正常工作,因为'new int'只能抛出'bad_alloc',从中无法恢复。自定义数据类型的构造函数可能会抛出更多的问题,因为那样你会从原始指针的部分初始化向量中泄漏内存。 'emplace_back'解决方案是唯一的故障安全解决方案。 (1) –