参考使用并集

Use of Union with reference

本文关键字:参考      更新时间:2023-10-16

在工作中,我一直在使用linux和C++11和C++14的GCC编译器。在一些工作中的代码中,我使用了一个并集来存储引用和指针,如下所示:(简化为重要部分)

struct MyStruct
{
    //Stuff
    union { double& x; double* x_ptr; };
    MyStruct(double& value) : x(value) {}
    //More stuff
};

我相信这段代码是清晰、可读、明确的,并且提供了一种方便的方式来存储可以转移到其他地方的引用。它提供了易于理解的语法糖,而不影响性能,同时提高了可读性。然而,当我试图在visualstudio15中使用这样的代码时,由于"double&类型的非法联合成员",代码未能编译。

  1. 根据标准,此代码是非法的,还是仅根据Visual Studio 2015
  2. 我可以让它在Visual Studio 2015中编译,或者提交错误报告/更改请求/其他什么吗
  3. 以这种方式使用工会是不好的做法吗

注意:在我的工作中,几乎所有的代码都是为Linux编写的,并使用GCC进行编译,对于我的特定项目,C++11是有保证的,GCC是唯一要使用的编译器。

编辑:请不要告诉我在联合中放置引用"没有意义"。当引用存储在结构中时,它占用的空间与指针相同。此外,以下使用clang编译:

struct MyStruct
{
    //This will compile
    union 
    { 
        struct { double& x; }; 
        double* x_ptr; 
    };
    //This won't compile; WHY?
    /*union 
    { 
        double& x;
        double* x_ptr; 
    };*/
    MyStruct(double& val) : x(val){}
    void Repoint(double& new_value) 
    { 
        x_ptr = &new_value; 
    }
};

为什么当引用被包装在匿名结构中时它会编译,而当它只是在联合中时却不会编译?

实例

除了@Brian:您可以使用例如std::reference_wrapper而不是简单的引用来编译它

#include <functional>
struct MyStruct
{
    //Stuff
    union { std::reference_wrapper<double> x; double* x_ptr; };
    MyStruct(double& value) : x(value) {}
    //More stuff
};
int main()
{
    double value = 123;
    MyStruct myStruct(value);
}

实例

联合包含引用成员是非法的。这大概是因为引用不是对象,并且不确定它们是否占用存储空间——所以引用与其他变量共享存储空间没有什么意义。

联合可以具有成员函数(包括构造函数和析构函数),但不能具有虚拟(10.3)函数。工会不应有基层。并集不得用作基类。如果并集包含非-引用类型的静态数据成员程序格式不正确。

([class.union]/2)