C++ 带括号和初始值设定项列表的自动

C++ 带括号和初始值设定项列表的自动,c++,language-lawyer,c++17,initializer-list,initializer,C++,Language Lawyer,C++17,Initializer List,Initializer,来自: 自C++17以来,autox0{1,2,3,4}不再被允许(当然,我们可以使用autox0={1,2,3,4};)。现在总是避免统一初始化(例如std::vector v({1,2,3,4});,即显式构造函数调用,以初始化器列表作为参数),类似于定义良好的auto x(7)(我也不会使用自己的构造…),我想到了以下几点: auto x({1, 2, 3, 4}); // -> std::initializer_list<int> x({1, 2, 3, 4}); a

来自:

自C++17以来,
autox0{1,2,3,4}不再被允许(当然,我们可以使用
autox0={1,2,3,4};
)。现在总是避免统一初始化(例如
std::vector v({1,2,3,4});
,即显式构造函数调用,以初始化器列表作为参数),类似于定义良好的
auto x(7)(我也不会使用自己的构造…),我想到了以下几点:

auto x({1, 2, 3, 4});
// -> std::initializer_list<int> x({1, 2, 3, 4});
autox({1,2,3,4});
//->std::初始值设定项_list x({1,2,3,4});
这是使用GCC 7.2.0(mingw64)编译的,但发出了警告(而评论版本也没有):

非类类型的列表初始值设定项不能用括号括起来 我在标准中找不到任何相关内容,因此现在的问题是(出于纯粹的兴趣…):


为什么这是不允许的?(这是否符合标准,或者我们需要考虑这是GCC错误吗?)

< P>这是病态的。简言之,大括号的init list不能在模板参数推导中推导,它被认为是

6) 参数p,其A是大括号的init list,但p不是std::initializer_list或对其中一个的引用:

首先,自动类型推断使用从函数调用中推断模板参数的规则

(强调矿山)

如果占位符是自动类型说明符,则推断的类型T' 替换T是使用模板参数的规则确定的 扣除额通过将auto的出现替换为 新发明的类型模板参数U或 初始化是复制列表初始化,带有
std​::​初始值设定项列表
。使用规则推导U的值 从函数调用中推断模板参数,其中P是 函数模板参数类型,对应参数为e。 如果扣除失败,则声明格式错误。[ 例如:

const auto &i = expr;
template<class T> void g(T);
g({1,2,3});                     // error: no argument deduced for T
i的类型是以下发明函数模板调用f(expr)中参数u的推导类型:

template <class U> void f(const U& u);
- 结束示例 ]


我很惊讶
autox0={1,2,3,4};
仍然是允许的。@VTT-如果不允许它,将破坏像
for(inti:{2,3,5,7})
@VTT这样的无辜构造,导致不允许
autox{1,2}
实际上也禁止了
=
变体,但标准委员会在这一部分没有遵循。另一方面,如果它被禁止,我上面的变体将是唯一有效的创建自动初始化列表的变体,这是新标准试图避免的,有利于统一初始化,这可能是ason允许上述变量…clang拒绝此项。@StoryTeller因为范围基循环映射到包含此类自动表达式的代码?假设有办法…我不是有两个模板演绎吗?第一个
{1,2,3,4}
创建一个
std::initializer\U list
,其中int是从参数中推导出来的,只有这样才能推导出auto的类型,其中
U
现在是
std::initializer\U list
,例如:
模板void f(T);auto x={1,2,3,4};f(x);
?或更短:
auto x={1,2,3,4};auto y(x)
作为副本列表中的
std::initializer\u list
初始化是一条特殊规则,仅适用于
auto
@Aconcagua。我要指出的是,一个实现可以随意添加任意数量的语言扩展。引自:符合要求的实现可能有扩展(包括附加的库函数),前提是它们不会改变任何格式良好的程序的行为。根据本国际标准,需要实现来诊断使用这种格式不良的扩展的程序。但是,这样做之后,它们可以编译和执行这种程序。@ArneVogel嗯,实际上发出了警告(参见问题),所以在这方面,根本没有bug。
template<class T> void g(T);
g({1,2,3});                     // error: no argument deduced for T