【发布时间】:2025-12-26 09:15:04
【问题描述】:
标准中的std::make_函数,如:
-
std::make_unique和std::make_shared std::make_tuplestd::make_from_tuple
所有内部都使用圆括号初始化而不是大括号。
例如,make_from_tuple as presented by the standard 选择返回 T(params...) 而不是 T{params...}。
结果如下是非法的:
auto vec = std::make_from_tuple<std::vector<int>>(std::make_tuple());
auto arr = std::make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8));
^ 从tuple 创建std::array,如上所述,是illegal also with C++20,因为p0960 - allowing initialization of aggregates from a parenthesized list of values 变为part of the C++20 spec 不允许对@ 进行此类初始化987654339@,因为它的内部类型是 T[size],它不能从值列表中初始化(括号已经被 std::array 初始化剥离)。
在它起作用的情况下,括号初始化与大括号的选择是有意义的:
auto vec2 = std::make_from_tuple<std::vector<int>>(std::make_tuple(2, 3));
// a vector with the values: {3, 3} surprise? :-)
(上面当然是玩具示例。提供的元组可以在外部提供)。
用 curly_make_from_tuple 喜欢:
template<typename T, typename tuple_t>
constexpr auto curly_make_from_tuple(tuple_t&& tuple) {
constexpr auto get_T = [](auto&& ... x){ return T{std::forward<decltype(x)>(x) ... }; };
return std::apply(get_T, std::forward<tuple_t>(tuple));
}
以上所有情况都可以,以一种人们可能认为更自然的方式:
auto arr = curly_make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8)); // {9, 8}
auto vec = curly_make_from_tuple<std::vector<int>>(std::make_tuple()); // {}
auto vec2 = curly_make_from_tuple<std::vector<int>>(std::make_tuple(2, 3)); // {2, 3}
问题是:为什么标准选择圆括号初始化而不是大括号?
相关链接:
类似的问题,从效率的角度来看:Why does implementation of make_tuple not return via brace initialisation?
一个不错的discussion and suggestions for adding curly brackets initialization option for the `make_` utilities。
提出make_from_tuple、P0209r2的原始论文似乎没有讨论T(params...)和T{params...}这两个替代方案,可能是因为所有类似的make_实用程序方法都已经使用圆括号初始化。
【问题讨论】:
-
函数调用总是使用圆括号。这就是语言语法。大括号用于初始化列表。
-
你问他们为什么使用
T(std::forward<decltype(x)>(x) ... )而不是T{std::forward<decltype(x)>(x) ... }? -
@NathanOliver 是的,忽略支持两者的花哨选项(如最后提供的第二个链接中所述)如果应该支持一个,为什么要支持圆括号?
-
不是初始化,是函数调用
std::make_unique、std::make_shared、std::make_tuple等。不初始化东西,它们返回对象,它们的优点是线程安全,简单等。 -
@asmmo 问题在于这些函数的内部实现。
标签: c++ initialization stdtuple list-initialization