【发布时间】:2017-07-16 03:30:10
【问题描述】:
考虑以下代码:
#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 的函数模板参数被规定为正如标准所说,是一个“非推断上下文”。”
【问题讨论】:
标签: c++ c++11 vector initializer-list