Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Member variable alias in class template specialization

Let's suppose I'm writing a Vector template class to represent points and vectors in an N-dimensional space. Something like the following:

template <typename T, int N>
struct Vector
{
    T data[N];
    // ...
};

Let's further assume that, for whatever reason, I want the user to be able to access data with meaningful names in the case of smaller vectors, e.g. by using v.xor v.y instead of v.data[0] and v.data[1].

I have two additional constraints.

  1. Access to the x or y component of a vector should not be written as a function call (e.g. it should be v.x, not v.x()).
  2. The following equality must hold sizeof(Vector<T, N>) == N * sizeof(T).

I looked at different possible approaches, including member variable references, tag dispatch and even CRTP but none of them satisfied all of my requirements.

Is it even possible to create such aliases? And if yes, how could one do it?

like image 763
J-M. Gorius Avatar asked Nov 30 '25 21:11

J-M. Gorius


1 Answers

(This is not an answer, it is a comment with a code example, which doesn't fit as a comment, and doesn't format well if it could be stuffed into a comment.)

Can you go the other direction, and express the vector as a bunch of fields, then map an index getter/setter to each of those fields?

Taking out the N template parameter to simplify the problem:

#include <iostream>
#include <stdexcept>

template <typename T>
struct Vector3
{
    T x;
    T y;
    T z;
    T operator[](int i) const
    {
        switch(i)
        {
            case 0:
                return x;
            case 1:
                return y;
            case 2:
                return z;
            default:
                throw std::out_of_range("out of range");
        }
    }
    T& operator[](int i)
    {
        switch(i)
        {
            case 0:
                return x;
            case 1:
                return y;
            case 2:
                return z;
            default:
                throw std::out_of_range("out of range");
        }
    }
};

int main()
{
    Vector3<float> v;
    v.x = 1.0f;
    v[1] = 2.0f;
    v.z = 3.0f;
    std::cout << v[0] << " " << v.y << " " << v[2] << '\n';
}
like image 133
Eljay Avatar answered Dec 03 '25 12:12

Eljay



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!