参考使用 Union

Use of Union with reference

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

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

我相信这段代码清晰、可读、明确,并且提供了一种方便的方式来存储可以转移到其他内容的引用。它提供了易于理解的语法糖,在提高可读性的同时不影响性能。但是,当我尝试在 visual studio 15 中使用这样的代码时,由于 "an illegal union member of type double&".

,代码无法编译
  1. 这个代码在标准下是非法的,还是在 Visual Studio 2015 下?
  2. 我可以在 Visual Studio 2015 年编译它,或者提交一个错误 report/change request/something?
  3. 以这种方式使用联合是不好的做法吗?

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

编辑:请不要告诉我将引用放入联合 "has no meaning"。当引用存储在结构中时,它占用与指针相同数量的 space 。此外,以下编译时使用 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; 
    }
};

为什么当引用包含在匿名结构中时它可以编译,但当它只是在联合中时却不能?

live example

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

A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. If a union contains a non- static data member of reference type the program is ill-formed.

([class.union]/2)

除了@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);
}

live example