繁体   English   中英

将花括号括起来的初始化列表作为结构体返回

[英]Return brace-enclosed initializer list as struct

给出下面用g++ -c test.cppg++ -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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM