我正在将现有的C代码导入/移植到C ++。我希望对现有代码主体进行尽可能少的更改,以最大程度地减少对现有代码的维护。该代码利用嵌套结构的静态命名初始化。快速的例子:
Car car =
{
.color = RED,
.tire.tread = OLD,
.tire.diameter = 27.106,
.tire.material.type = RUBBER,
.tire.material.density = 700,
};
我知道是these are called designated initializers。
我了解了GNU initializers,但还没有弄清楚如何用它来实现层次结构。
我读过designated initializers are supported in g++ with c++11 enabled,但对我来说似乎不起作用。
我正在移植的代码具有至少四层层次结构的初始化页面。因此,我正在尝试寻找一种不会涉及太多的简单转换。
我正在寻找以下可能的解决方案之一:
我正在使用g ++版本
g++.exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
使用这样的嵌套指定的初始化程序似乎有点极端。以下内容在clang-cl
(在Visual Studio 2019中)和本机MSVC
编译器中都有效(但后者仅具有/std:c++latest
选项,该选项使用C ++ 20标准草案):
struct inner {
int x, y;
double z;
};
struct outer {
char a;
double b;
inner c;
};
outer my_outer = { .a = 'a', .b = 1.2, .c = { .x = 3, .y = 4, .z = 5.6 } };
使用clang-cl
,初始化程序可以缩写为以下形式:
outer my_outer = { .a = 'a', .b = 1.2, .c.x = 3, .c.y = 4, .c.z = 5.6 };
但MSVC
在这种情况下投诉:
错误C7558:在标准C ++中不允许嵌套成员访问指定的初始值设定项;使用嵌套的初始化程序列表
因此,对于您的示例,您可以尝试以下操作:
Car car =
{
.color = RED,
.tire = {
.tread = OLD,
.diameter = 27.106,
.material.type = RUBBER,
.material.density = 700,
}
};
关于cppreference的主题有一个有用的'讨论',这一部分值得注意:
...每个指定者必须命名T的直接非静态数据成员,并且表达式中使用的所有指示符必须以相同的顺序出现作为T的数据成员。