请参见Should I use () or {} when forwarding arguments?。
foo
是一个std::vector
的克隆。
在N4140中,unique.ptr.create指定了std::make_unique
如下:
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
备注:除非
T
不是数组,否则此函数不得参与重载决议。返回值:
unique_ptr<T>(new T(std::forward<Args>(args)...))
。
这意味着实现必须使用()
而不是{}
来初始化对象。例如,以下示例代码将导致编译错误:
auto s1 = std::make_unique<foo>(3, 1).get()->size();
auto s2 = std::make_unique<foo>(1).get()->size();
auto s3 = std::make_unique<foo>(2).get()->size();
std::cout << s1 << s2 << s3;
输出结果为312
,如果使用{}
(在std::make_unique
内部),则输出结果为211
。因为无法推导初始化器列表,所以必须显式传递std::initializer_list
才能获得后者的结果。问题是,为什么没有提供这样的重载?
namespace test
{
template <class T, class Deduce>
std::unique_ptr<T> make_unique(std::initializer_list<Deduce> li)
{
return ::std::make_unique<T>(li);
}
};
int main()
{
auto p1 = test::make_unique<foo>({3, 1}).get()->size();
auto p2 = test::make_unique<foo>({1}).get()->size();
auto p3 = test::make_unique<foo>({2}).get()->size();
std::cout << p1 << p2 << p3;
}
输出 211
。
我不认为“你可以自己写”或“为了避免标准膨胀”这些理由是很好的理由。提供这个重载有什么缺点吗?
make_unique<std::pair<int, int>>(1, 73);
可以完美地工作。如果有人执行make_unique<std::pair<int, int>>({1, 73});
,那就是他们的问题了。 - user6319825new T(std::forward<Args>(args)...)
而不是像对于optional一样由实现自行决定:“如果直接非列表初始化一个类型为T
的对象,则使用参数std::forward <Args>(args)
初始化包含的值....”这让我想到至少在make_unique
方面有一些讨论。 - user6319825optional
支持initializer_list
。 - Niall