How to set attribute names in template parameters?

98 views Asked by At

I have a vector class :

template <typename T>
class Vector2 {
    public:
      T x, y;
    Vector2(T x, T, y) : x{x}, y{y} {}
}

And I would like get different accessors depending on the context:

Vector2<float, x, y> xy;
xy.x = 42;

Vector2<float, u, v> uv;
uv.u = 42;

Is something like that possible in C++? More specifically, is this possible in C++03?

Context

I work on an embedded firmware in C++ for a DC/DC voltage converter. I have different values such as voltages, current... Some transformations can be applied from a 3-phase current (u,v,w) into 2-phase static (a,b) and 2-phase rotating frame (d, q). It would be more readable to have specific types such as:

using CurrentDQ = Vector2<float, d, q>
using CurrentAB = Vector2<float, a, b>
using Current3 = Vector<float, u, v, w>
2

There are 2 answers

0
HolyBlackCat On

The closest you can do is this:

template <typename T>
struct ElemsUV {T u, v;};

template <typename T>
struct Vector : T {};

Vector<ElemsUV<float>> vec;

// Or:
// template <typename T, template <typename> class E> struct Vector : E<T> {};
// Vector<float, ElemsUV> vec;

You can of course split u and v into separate structures, but a single big one looks more convenient to me.

Then the Elems?? structures would have a uniform interface for Vector<...> to interact with, e.g.:

template <typename T>
struct ElemsUV
{
    T u, v;
    T &get_x() {return u;}
    T &get_y() {return v;}
};

And Vector would internally use only get_x(), get_y() to access the element.

2
Joel On

I am not sure about C++03 but you can have unions to access the same data with different variables. You could create your stuct like this:

template <typename T>
class Vector2 {
public:
    union
    {
        T x, u;
    };
    union
    {
        T y, v;
    };
    Vector2(T x, T y) : x{ x }, y{ y } {}
};

and then access the data like this:

Vector2<int> vec(1, 2);
vec.x;
vec.u;

and they will both have the same value/address.