使用Union参考

J. *_*rez 7 c++ syntax unions c++11 visual-studio-2015

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

struct MyStruct
{
    //Stuff
    union { double& x; double* x_ptr; };
    MyStruct(double& value) : x(value) {}
    //More stuff
};
Run Code Online (Sandbox Code Playgroud)

我相信这段代码清晰,可读,明确,并提供了一种方便的方式来存储可以转移到其他东西的引用.它提供易于理解的语法糖,而不会降低性能,同时提高可读性.但是,当我尝试在visual studio 15中使用这样的代码时,代码由于"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; 
    }
};
Run Code Online (Sandbox Code Playgroud)

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

live example

m.s*_*.s. 10

除了@Brian之外:您可以使用eg 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);
}
Run Code Online (Sandbox Code Playgroud)

live example


Bri*_*ian 9

联盟包含引用成员是非法的.这可能是因为引用不是对象,并且未指定它们是否占用存储空间 - 因此引用与其他变量共享其存储空间毫无意义.

联合可以具有成员函数(包括构造函数和析构函数),但不具有虚函数(10.3).工会不得有基类.联合不得用作基类.如果联合包含引用类型的非静态数据成员,则程序格式错误.

([class.union/2)

  • @JorgePerez 可能是这样。在某些情况下它也可能被优化。标准*未指定*。 (2认同)