user491880
user491880

Reputation: 4869

How to use multiple names for class members in C++

So I have a vec4 class that uses members x,y,z,w which you can access using

point.x point.y etc.

However I want to reuse this vec4 class to be my color class (it already supports scalar multiplication, operator overloading lots of other nice stuff) I just want to be able to refer to the members using another notation:

color.r color.g color.b

etc.

Is there anyway I can do this using a macro or other syntactic sugar?

Upvotes: 0

Views: 963

Answers (3)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136208

You can easily do that with standalone accessor functions:

struct vec4 { double x, y, z; };

double& get_r(vec4& v) { return v.z; }
// and so on

Upvotes: 0

Miguel Grinberg
Miguel Grinberg

Reputation: 67479

Unless you have a good amount of common behavior between a vector and a color I think this is a bad idea. But since you asked, here is a possible way to do that.

If you make the x, y, z and w members private and provide accessor methods to get to them, then it is easy to provide two alternative ways to refer to the same member variables. For example:

class vec4 {
private:
    float _x, _y, _z, _w;
public:
    // vector getter/setters
    float& x() { return _x; }
    float& y() { return _y; }
    float& z() { return _z; }
    float& w() { return _w; }

    // color getter/setters
    float& r() { return _x; }
    float& g() { return _y; }
    float& b() { return _z; }
    float& a() { return _w; }

};

vec4 my_color;
my_color.r() = 1.0f;
my_color.g() = 0.0f;
my_color.b() = 0.0f;
my_color.a() = 1.0f;

Upvotes: 0

gwiazdorrr
gwiazdorrr

Reputation: 6329

If you are using Visual Studio (and are sure that it is the only target IDE...) you can use the following:

#include <cassert>

union vec4
{
    struct 
    {
        float x;
        float y;
        float z;
        float w;
    };
    struct
    {
        float r;
        float g;
        float b;
        float a;
    };
};

int main()
{
    vec4 vec = { 0 };
    vec.y = 10.0f;
    assert(vec.g == 10.0f);
    return 0;
}

It will yield warnings warning C4201: nonstandard extension used : nameless struct/union, though you can disable it.

EDIT: as it turns out gcc supports this extension as well.

Upvotes: 1

Related Questions