c++ - 将大括号括起来的初始化列表作为结构返回
问题描述
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
(这称为匿名联合),然后可以访问联合成员的名称,就好像它们是封闭结构的成员一样。
推荐阅读
- google-app-engine - 为什么谷歌应用引擎似乎使用旧代码?
- pine-script - 为什么实时交易中的策略只提示一次?
- java - Springboot启动时的线程,无法读取属性文件
- salesforce - Conga CLM 和 X-Author 模板认证考试?
- javascript - 执行时发生异常:android.os.ParcelableException:java.io.IOException:仅请求内部,但空间不足
- javascript - 有没有办法缩短大部分重复的 if 语句?
- css - 在 JSF 项目中实现 AdminLTE 主题时图标不起作用
- javascript - 如何在 pug 模板中显示图像
- xml - 如何使用属性设置xml值
- machine-learning - 在 keras 中使用 LSTM 进行时间序列预测 - 收敛问题