当我阅读C++参考资料时,我对这段话有一个问题:
注意:指定初始化顺序错误,嵌套指定初始化,指定初始化程序和常规初始化程序的混合初始化程序和指定的数组初始化都是在C编程语言中支持,但在C++中不允许。
是否有任何技术原因阻止C++支持无序指定的初始化?
是的,其基本原理在附录C中介绍(资料性(兼容性特别是[diff.dcl]p10(emphasis mine(:
受影响的子条款:[dcl.init.agr]更改:在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表达式语法冲突。嵌套指示符很少使用。
提案的第一次修订也讨论了这个主题:
为了满足这些对保证拷贝省略的期望,我们要求出现指示符作为数据成员声明序列的子序列,以便计算顺序与声明顺序匹配,并且在指定的初始化中也是从左到右的文本
您可以在此处获取最后一次修订。
只有一小部分来自C的指定初始化选项是痛苦的。也许它将来会被纠正。目前,一些编译器的严格程度还不如C++20标准。这个片段:
struct A {int x, y;};
A a = {.y=2, .x=4};
编译时带有警告,并且使用clang-10.0.0
及更新版本运行良好(请参阅https://godbolt.org/z/Ybnzz5chx)。