C++ 为什么标准首选“make”的圆括号初始化<;什么>;`?

C++ 为什么标准首选“make”的圆括号初始化<;什么>;`?,c++,initialization,stdtuple,list-initialization,C++,Initialization,Stdtuple,List Initialization,标准中的std::make功能,例如: std::make_unique和std::make_shared std::make\u tuple std::从元组生成 它们都使用内部圆括号,而不是花括号 例如,正在选择返回T(params…,而不是T{params…} 结果是,以下行为是非法的: auto vec = std::make_from_tuple<std::vector<int>>(std::make_tuple()); auto arr = std::ma

标准中的
std::make
功能,例如:

  • std::make_unique
    std::make_shared
  • std::make\u tuple
  • std::从元组生成
它们都使用内部圆括号,而不是花括号

例如,正在选择返回
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));
(以上当然是玩具示例。提供的元组可以在外部提供)

使用
curly\u make\u from\u tuple
类似:

模板
constexpr自动卷曲从元组生成(元组和元组){
constexpr auto get_T=[](auto&&…x){返回T{std::forward(x)…};};
返回std::apply(get_T,std::forward(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}
auto arr=curly_make_from_tuple(std::make_tuple(9,8));//{9, 8}
auto-vec=curly_make_from_tuple(std::make_tuple());//{}
auto vec2=curly_make_from_tuple(std::make_tuple(2,3));//{2, 3}
问题是:为什么标准选择圆括号而不是花括号?


相关链接:

从效率的角度来看,类似的问题:

A很好


最初的论文提出了
make_from_tuple
,似乎没有讨论两个备选方案
T(params…
T{params…}
,可能是因为所有类似的
make\uu
实用程序方法都已经使用圆括号初始化了。

因为在C++98中无法使用带括号的init list初始化结构

因此,为了保持一致性,新的标准库功能使用了与STL中使用的相同的初始化形式


此外,出于兼容性原因,它从未更改为列表初始化:列表初始化不一定与等效的括号内初始化形式具有相同的含义。

函数调用始终使用圆括号。这就是语言语法。花括号用于初始值设定项列表。您是否想知道为什么它们使用
T(std::forward(x)…
而不是
T{std::forward(x)…}
?@NathanOliver是的,忽略了支持这两个选项的奇特选项(如最后提供的第二个链接所述)如果应该支持一个,为什么使用圆括号?这不是一个初始化,它是一个函数调用
std::make_unique
std::make_shared
std::make_tuple
,等等。不初始化东西,它们返回对象,它们的优点是线程安全、简单,等等@asmmo问题在于这些函数的内部实现。C++11之前的哪个库函数创建了这样的对象?可能没有,因为它依赖于可变模板。所以,如果所有这些函数都出现在C++11或之后,它可能会使用大括号初始化。当然,如果不是用一种奇特的方法来支持两者,就必须选择一个,但委员会是否考虑了两者?这是一个有意的决定吗?@AmirKirsh以STL分配器为例,用于复制构造。
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}