【发布时间】:2019-08-04 02:42:17
【问题描述】:
https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique 写道,std::make_unique 可以实现为
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
这不适用于没有构造函数的普通结构。这些可以被大括号初始化,但没有非默认构造函数。示例:
#include <memory>
struct point { int x, z; };
int main() { std::make_unique<point>(1, 2); }
Compiling this 会让编译器抱怨缺少 2 参数构造函数,这是正确的。
我想知道,是否有任何技术原因不使用大括号初始化来定义函数?如
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
}
works well enough 用于上述场景。是否还有其他合法的用例会被破坏?
看到总体趋势似乎更喜欢大括号进行初始化,我认为在该模板中制作大括号将是规范的选择,但标准不这样做的事实可能表明我错过了一些东西。
【问题讨论】:
-
当你打电话给
make_unique<vector<int>>(10,20)时考虑一下你想得到什么?具有 10 个项目的向量,所有 20 个值(当在 make_unique 中使用 () 时),或具有 2 个项目的向量 10,20(当使用 {} 时,向量具有采用 initializer_list 的构造函数)。 -
如果有什么安慰的话,p0960 正在筹备中。未来的 C++ 版本可能会支持聚合,而无需更改工厂库函数工作方式的实现。
-
尽管可以想象,今天在
std::is_aggregatetrait 的帮助下支持类似的东西是可能的。我猜人们觉得最好有一个语言解决方案,而不是一个库。 -
“看到总体趋势似乎更喜欢使用大括号进行初始化”我担心由于矢量等问题不再有这种趋势。
-
来自this proposal,匹配
make_shared。我还没有找到为什么make_shared选择一种方式而不是另一种方式。shared_ptr虽然在 TR1 中,早在统一初始化语法存在之前 - 不确定当时是否存在make_shared。
标签: c++ initialization c++14 unique-ptr c++-standard-library