简体   繁体   English

为什么 C++20 不支持乱序指定初始值设定项?

[英]Why C++20 doesn't support out-of-order designated initializer?

While I was reading C++ reference , I had a question about this paragraph:在阅读C++ 参考时,我对这一段有疑问:

Note: out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C++.注意:乱序指定初始化、嵌套指定初始化、指定初始化器和常规初始化器的混合、数组的指定初始化在C编程语言中都是支持的,但在C++中是不允许的。

Is there any technical reason that prevents C++ from supporting out-of-order designated initialization?是否有任何技术原因阻止 C++ 支持乱序指定初始化?

Yes, the rationale is covered in Annex C (informative) Compatibility specifically [diff.dcl]p10 ( emphasis mine ):是的,基本原理在附录 C(信息性)兼容性[diff.dcl]p10重点是我的)中有介绍:

Affected subclause: [dcl.init.aggr] Change: In C++, designated initialization support is restricted compared to the corresponding functionality in C. In C++, designators for non-static data members must be specified in declaration order , designators for array elements and nested designators are not supported, and designated and non-designated initializers cannot be mixed in the same initializer list.受影响的子条款:[dcl.init.aggr] 更改:在 C++ 中,与 C 中的相应功能相比,指定初始化支持受到限制。在 C++ 中,必须在声明顺序中指定非静态数据成员的指示符、数组元素的指示符和不支持嵌套指示符,并且指定和非指定初始化器不能混合在同一个初始化器列表中。 Example:例子:

 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 = {.ax = 0}; // valid C, invalid C++ struct A c = {.x = 1, 2}; // valid C, invalid C++

Rationale: In C++, members are destroyed in reverse construction order and the elements of an initializer list are evaluated in lexical order, so field initializers must be specified in order.基本原理:在 C++ 中,成员以相反的构造顺序销毁,初始化列表的元素按词法顺序计算,因此必须按顺序指定字段初始化程序。 Array designators conflict with lambda-expression syntax.数组指示符与 lambda 表达式语法冲突。 Nested designators are seldom used.很少使用嵌套指示符。

The first revision of the proposal also discusses this topic: 提案第一次修订也讨论了这个话题:

To meet these expectations for guaranteed copy elision, we require the designators to appear as a subsequence of the data member declaration sequence, so that the evaluation order matches the declaration order, and it is also textually lefttoright in designated initialization为了满足保证复制省略的这些期望,我们要求指示符作为数据成员声明序列的子序列出现,以便评估顺序与声明顺序匹配,并且在指定初始化中也是从左到右的文本

You can obtain the last revision here .您可以在此处获取最新修订版。

Having only a small fraction of designated initialization options from C is painful.只有一小部分来自 C 的指定初始化选项是痛苦的。 Perhaps it will be rectified in the future.也许将来会得到纠正。 For now, some compilers are a bit less strict than C++20 standard.目前,一些编译器的严格程度低于 C++20 标准。 This snippet:这个片段:

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

compiles with a warning and runs fine with clang-10.0.0 and newer (see https://godbolt.org/z/Ybnzz5chx ).编译时发出警告并在clang-10.0.0和更新版本中运行良好(请参阅https://godbolt.org/z/Ybnzz5chx )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM