【问题标题】:Why do default member values prohibit use of braced-list initialization? [duplicate]为什么默认成员值禁止使用花括号初始化? [复制]
【发布时间】:2016-05-25 20:23:45
【问题描述】:

考虑这个结构:

struct S { int index; };

它可以像这样使用花括号列表进行初始化:

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

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

struct S { int index = -1; };

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

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

我正在使用 VS2015 编译器。

【问题讨论】:

  • 您是否需要标准报价,确认您的编译器确实按照您测试的方式运行,是否/何时会发生变化的信息,或者让我们找到所有的综合文档和记录由遗漏或委托决定的标准化会议?还是以上所有?我的意思是,“为什么:是一个问题,但它是一个模糊的问题。请具体一点,并提出一个与主题相关且足够狭窄以便回答的问题。
  • @Yakk 请看答案。在这种情况下,“为什么”是一个有效的问题,因为代码格式正确。问题是 C++14 的这个特殊特性(解除了之前的限制,在 OP 中体验和描述)还没有在 VS 中实现。因此,设置任何编译器标志等不是我的错误、标准或遗漏。因为我不知道我问的问题到底是什么。
  • @Yakk 我正试图找到关于询问“为什么”问题的精彩元线程,但我找不到它...... gah......
  • @Barry: This one?
  • @BenVoigt 是的!谢谢。

标签: c++ struct visual-studio-2015


【解决方案1】:

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

聚合是一个数组或一个类(第 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 聚合初始化。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2021-06-13
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
相关资源
最近更新 更多