C ++ - 有没有办法为字段创建别名

时间:2014-04-19 20:46:37

标签: c++ c++11 alias

有没有办法为C ++ 11中的class / stuct创建别名? 我的意思

我上课了

class Vector4
{
    public:
        float X,Y,Z,W;
}

我有别名

typedef Vector4 Color;

有没有办法为Vector4 X,Y,Z,W字段创建别名以用作颜色R,G,B,A?

3 个答案:

答案 0 :(得分:4)

使用匿名联合(没有匿名结构,虽然它们是常见的扩展名),只需像这样定义Vector4。

typedef struct Vector4
{
    union{float X; float R;};
    union{float Y; float G;};
    union{float Z; float B;};
    union{float W; float A;};
} Vector4;
typedef Vector4 Color;

如果您无法重新定义Vector4,您可能只需定义与布局兼容的标准布局类并使用可怕的reinterpret_cast。 这是有效的,因为具有布局兼容成员的标准布局类是兼容的。

struct Color
{
    float R, G, B, A;
}

标准报价:

  

标准布局类是一个类:
   - 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员,
   - 没有虚函数(10.3),没有虚基类(10.1),
   - 对所有非静态数据成员具有相同的访问控制(第11条),
   - 没有非标准布局基类,
   - 要么在最派生类中没有非静态数据成员,要么最多只有一个基类   非静态数据成员,或没有具有非静态数据成员的基类,以及
   - 没有与第一个非静态数据成员相同类型的基类。

     

标准布局结构是使用class-key结构或class-key类定义的标准布局类   标准布局联合是使用类 - 键联合定义的标准布局类。

答案 1 :(得分:2)

您可以通过以下方式为成员变量创建alias

template <class Base, class Type, Type Base::*field>
struct Field {
   operator Type () const { return  base->*field; }
   Field& operator = (const Type& v) { base->*field = v; return *this; }

   Base* base;
};

所以,你可以这样输入Color

class Color {
   Vector4 v;
public:
   Color() : v{}, R{&v}, G{&v}, B{&v}, A{&v} {}
   Field<Vector4, float, &Vector4::X> R;
   Field<Vector4, float, &Vector4::Y> G;
   Field<Vector4, float, &Vector4::Z> B;
   Field<Vector4, float, &Vector4::W> A;
};

当然,此Color类型不再是Vector4 ...

的简单别名

答案 2 :(得分:2)

这应该有用。

class Vector4
{
    public:

        Vector4 : X(0), Y(0), Z(0), W(1), R(X), G(Y), B(Z), A(W) {}

        float X,Y,Z,W;
        float& R;
        float& G;
        float& B;
        float& A;
};

但是,你必须实现正确的复制构造函数和复制赋值运算符。

更好的选择是通过成员函数访问它们。

class Vector4
{
    public:

        Vector4 : X(0), Y(0), Z(0), W(1){}

        float X,Y,Z,W;
        float& R() { return X ;}
        float& G() { return y ;}
        float& B() { return z ;}
        float& A() { return w ;}

        float const& R() const { return X ;}
        float const& G() const { return y ;}
        float const& B() const { return z ;}
        float const& A() const { return w ;}
};