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}