TL;DR:Clang 和 GCC 拒绝您的代码是错误的。CWG 1630 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518无论选择的默认构造函数如何,该决议都使默认初始化格式良好explicit
or not.
In the variation of your code in which i
is private
, A
is not an aggregate, as these cannot have private members. As long as i
is public
, however, A
is an aggregate1, and no constructor is invoked since aggregate initialization is performed (see blue box), so your constructor being explicit
is irrelevant.
但是,一旦引入私有成员,就需要按照红框进行值初始化。因此 [dcl.init]/(8.2) 适用:
[dcl.init]/(7.1) 定义了这种情况的默认初始化:
§13.3.1.3 给出
对于[...]默认初始化,候选者
函数是对象所在类的所有构造函数
已初始化。
任何时候都不会考虑原始上下文(复制或直接初始化)。 (§13.3.1.7 也不适用。)事实上,这是有意为之的;看CWG #1518 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518:
该问题已通过决议解决第1630期 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1630: 默认初始化现在使用 13.3.1.3 [over.match.ctor],它现在允许使用显式构造函数进行默认初始化。
Clang 和 GCC(和 VC++)尚未实现相应的 DR,因此拒绝 C++14 模式下的代码是不正确的。
1)
Your class has a user-declared constructor, but it isn't user-provided, i.e. not impeding your class from being an aggregate. Recall the definition in [dcl.init.aggr]/1:
An 总计的是一个数组或一个类(第 9 条),没有用户提供
构造函数 (12.1),没有私有或受保护的非静态数据成员
(第 11 条),无基类(第 10 条),无虚函数
(10.3)。