18

在阅读C++ 参考资料时,我对这一段有疑问:

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

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

4

2 回答 2

17

是的,附件 C(信息性)兼容性中涵盖了基本原理,特别是[diff.dcl]p10强调我的):

受影响的子条款:[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 表达式语法冲突。很少使用嵌套指示符。

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

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

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

于 2018-11-11T15:57:12.980 回答
3

只有一小部分来自 C 的指定初始化选项是痛苦的。也许将来会被纠正。目前,一些编译器没有 C++20 标准那么严格。这个片段:

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

编译时出现警告,并且在clang-10.0.0更新版本中运行良好(请参阅https://godbolt.org/z/Ybnzz5chx)。

于 2021-04-16T03:53:32.383 回答