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

M. *_* E. 9 c++ designated-initializer c++20

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

注意:C编程语言支持无序指定初始化,嵌套指定初始化,指定初始化器和常规初始化器的混合以及指定的数组初始化,但C++中不允许这样做.

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

Sha*_*our 12

是的,理由是覆盖在附件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++
Run Code Online (Sandbox Code Playgroud)

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

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

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

您可以在此处获取最新修订版.

  • 如果将其指定为以下位置,我看不到任何问题:初始化顺序将与成员顺序相同。以前已经有init列表了。如果允许的话会有负面影响吗? (4认同)
  • 我最近还做了一个[推特民意调查](https://twitter.com/shafikyaghmour/status/1007671525313413122) (2认同)

Pau*_*zak 8

Having only a small fraction of designated initialization options from C is painful. Perhaps it will be rectified in the future. For now, some compilers are a bit less strict than C++20 standard. This snippet:

struct A {int x, y;};
A a = {.y=2, .x=4};
Run Code Online (Sandbox Code Playgroud)

compiles with a warning and runs fine with clang-10.0.0 and newer (see https://godbolt.org/z/Ybnzz5chx).