为什么默认成员值禁止使用支持列表初始化

Why do default member values prohibit use of braced-list initialization?

本文关键字:支持 列表 初始化 禁止 默认 成员 为什么      更新时间:2023-10-16

考虑这个结构:

struct S { int index; };

它可以使用支持列表进行初始化,如下所示:

S s{10}; //s::index becomes 10

但是,如果我为成员指定一个默认值:

struct S { int index = -1; };

支持列表初始化给我一个编译器错误,它无法将initializer list转换为S。我怀疑这可能与为结构生成的默认构造函数有关,因为我已经指定了默认值。但为什么初始值设定项列表不能覆盖它呢?

我想要这样做的原因是,我想用值初始化结构,或者将其默认为一些"无效"的默认值。由于这个限制,我必须自己指定一个构造函数,或者每次都显式初始化"无效"默认值。

我使用的是VS2015编译器。

在C++11中,聚合在[dcl.init.agr]中定义为:

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有大括号或非静态数据成员的同等初始化器(9.2),没有私有或受保护的非静态数据员(第11条),无基类(第10条),也无虚拟函数(10.3)。

由于N3605删除了该条件,这一点后来得到了改进(此后重新格式化,将这些条件显示为项目符号列表。是的可读性)。

因此,在C++11中,这个:

struct S { int index = -1; };
int main() {
S s{10};
}

格式错误,因为S不符合聚合条件,所以我们不尝试进行聚合初始化,并且int没有匹配的构造函数。

但是在C++14中,S是一个聚合,因此代码的格式很好。因此,您要么是在C++11模式下编译,要么VS2015还不支持C++14聚合初始化。