为什么C++20不支持乱序指定初始化器?

问题描述 投票:0回答:2

当我阅读C++参考时,我对这一段有一个疑问:

注意:乱序指定初始化、嵌套指定 初始化,指定初始化器和常规初始化器的混合 初始化器和数组的指定初始化都是 C 编程语言支持,但 C++ 不允许。

是否有任何技术原因阻止 C++ 支持乱序指定初始化?

c++ c++20 designated-initializer
2个回答
29
投票

是的,其基本原理包含在附录 C(资料性)中 兼容性,特别是[diff.dcl]p9强调我的):

受影响的子条款:[dcl.init.aggr] 更改:在 C++ 中,指定 与相应的初始化支持相比,初始化支持受到限制 C 中的功能。在 C++ 中,非静态数据成员的指示符 必须按声明顺序指定,数组元素的指示符 和嵌套指示符不受支持,并且指定和 非指定初始化器不能混合在同一个初始化器中 列表。示例:

struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2};  // valid C, invalid C++
int arr[3] = {[1] = 5};         // valid C, invalid C++
struct B b = {.a.x = 0};        // valid C, invalid C++
struct A c = {.x = 1, 2};       // valid C, invalid C++

基本原理:在 C++ 中,成员按相反的构造顺序被销毁,并且初始值设定项列表的元素按词法顺序求值,因此必须按顺序指定字段初始值设定项。 数组指示符与 lambda 表达式语法冲突。 嵌套指示符很少使用。

提案的第一次修订也讨论了这个话题:

为了满足保证复制省略的这些期望,我们要求指示符出现 作为数据成员声明序列的子序列,以便求值顺序 与声明顺序匹配,并且在指定初始化中也是从左到右的文本

您可以在此处获取最新版本。


8
投票

只有一小部分来自 C 的指定初始化选项是痛苦的。也许将来会得到纠正。目前,一些编译器比 C++20 标准稍微宽松一些。这个片段:

struct A {int x, y;};
A a = {.y=2, .x=4};

编译时会出现警告,并且可以在

clang-10.0.0
及更新版本中正常运行(请参阅 https://godbolt.org/z/Ybnzz5chx)。

© www.soinside.com 2019 - 2024. All rights reserved.