[英]Return brace-enclosed initializer list as struct
给出下面用g++ -c test.cpp
或g++ -std=c++17 -c test.cpp
编译的简化代码
#include <cstddef>
struct sd_bus_vtable {
union {
struct {
size_t element_size;
} start;
struct {
const char *member;
const char *signature;
} signal;
} x;
};
sd_bus_vtable get()
{
return {
.x = {
.signal = {
.member = "",
.signature= "",
}
}
};
}
它在 GCC 9.2.0 和 clang 5/6 上编译良好,但在 8.3.0 或 7.4.0 上失败并显示以下错误消息:
test.cpp:25:5: error: could not convert ‘{{{"", ""}}}’ from ‘<brace-enclosed initializer list>’ to ‘sd_bus_vtable’
};
为了解决这个问题,函数get()
可以改变如下,但它看起来不那么干净......
sd_bus_vtable get()
{
struct sd_bus_vtable t = {
.x = {
.signal = {
.member = "",
.signature= "",
}
}
};
return t;
}
问题是,上面的代码是否有效? 如果是,它是否会触发 GCC 中已在 GCC9 中修复的某些错误?
指定的初始值设定项语法尚不在标准 C++ 中。 它计划包含在 C++20 中,但尚未最终确定或发布。
因此,您依赖支持此即将推出的功能作为扩展的编译器。
在已发布的 C++ 标准中,没有办法为第一个联合成员以外的联合成员提供这样的初始化程序。 (您可以在类定义中使用默认成员初始值设定项)。
同时,以下代码将起作用:
sd_bus_vtable get()
{
sd_bus_vtable r{};
r.x.signal = {"", ""};
return r;
}
注意:此方法(使用赋值运算符切换联合的活动成员)仅在所有联合成员都具有普通构造函数和析构函数时才有效。 否则,您需要手动销毁和创建 .
也可以省略名称x
(这称为匿名 union ),然后可以访问联合成员的名称,就像它们是封闭结构的成员一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.