问题描述
还有其他有关初始化嵌套结构数组的文章。但是,遵循Stackoverflow其他地方给出的建议以及指向Aggregate Initialization的链接并不能帮助我解决问题。
我的情况是,我正在Vulkan图形API中初始化许多嵌套结构。
但是,在查看其他代码进行解释时,我遇到了以下“ C”初始化(请注意,我正在添加定义的结构和相关代码)
Vulkan typedefs
typedef union VkClearColorValue {
float float32[4];
int32_t int32[4];
uint32_t uint32[4];
} VkClearColorValue;
typedef struct VkClearDepthStencilValue {
float depth;
uint32_t stencil;
} VkClearDepthStencilValue;
typedef union VkClearValue {
VkClearColorValue color;
VkClearDepthStencilValue depthStencil;
} VkClearValue;
有问题的“ C”代码
const VkClearValue clear_values[2] = {
[0] = {.color.float32 = {0.2f,0.2f,0.2f}},[1] = {.depthStencil = {demo->depthStencil,0}},};
在C99和最新的gcc编译器中,“ C”表示法是合法的。
但是,当我将其应用于C ++时,会出现错误。
回到聚合初始化规则,“ C”表示法在C ++ 17中应合法。但是,在编译时,我得到以下错误:错误:“。”之前的预期主表达式。令牌
很显然,我的假设是错误的。因此,任何人都可以提供有关如何使其在C ++ 17中合法化的指南。
解决方法
回到聚合初始化规则,“ C”表示法在C ++ 17中应合法
您已经错误地认为,因为您已正确得出结论。从第一个标准版本开始,C ++就已经进行了汇总初始化,但是它不支持C99中添加的所有初始化。例如,指定的初始化程序根本不在C ++ 17中。
因此,琐碎的联合只能在第一个成员处于活动状态时进行初始化,例如在C89中。要激活另一个成员,必须在初始化后对其进行分配。为此,可以使用const对象。
C ++ 20添加了指定的初始化程序,但即使如此,也仅允许C的子集。以下在C ++ 20中格式正确:
const VkClearValue clear_values[2] = {
{.color {.float32 = {0.2f,0.2f,0.2f}}},{.depthStencil = {42,0}},};
,
在c ++中,这不是aggregate initialization的有效形式,即使在c语言中也是如此。实际上,有一个注释:
注意:乱序的指定初始化,嵌套的指定初始化,指定的初始化程序和常规初始化程序的混合以及数组的指定初始化在C编程语言中均受支持,但在C ++中是不允许的。
struct A { int x,y; }; struct B { struct A a; }; struct A a = {.y = 1,.x = 2}; // valid C,invalid C++ (out of order) int arr[3] = {[1] = 5}; // valid C,invalid C++ (array) struct B b = {.a.x = 0}; // valid C,invalid C++ (nested) struct A a = {.x = 1,2}; // valid C,invalid C++ (mixed)