Member variable aliasing a function?

So, one can do stuff like this using #defines:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <array>

#define x arr[0]
#define y arr[1]
#define z arr[2]

class Point
{
public:
  Point(const float _x, const float _y, const float _z)
  {
    x = _x;
    y = _y;
    z = _z;
  }

  std::array<float, 3> arr;
};


int main(int argc, char** argv)
{
  Point p(0, 1, 2);
  for (auto i : p.arr)
    std::cout << i << std::endl;
}


... that is, to be able to reference the same data by "member variables" as by referencing a stl container.

But defines are the devil's work - adding in a "#define x arr[0]" is a dangerous statement. I'd really like some nice clean C++ method (C++11 or C++14 are just fine) to do this without defines, but so far I'm drawing a blank. If arr wasn't an STL container, if we just wanted a pointer-based array, I could do it this way:

1
2
3
4
5
6
7
8
9
 class Point
{
  ...

  float x __attribute__ ((aligned (sizeof(float))));
  float y __attribute__ ((aligned (sizeof(float))));
  float z __attribute__ ((aligned (sizeof(float))));
  float*const arr = &x;
};


... but you obviously can't do that if arr is an STL container.

Thoughts? The best I've come up with is to make x, y, and z function pointers, but then you can't call them like p.x, you have to call them like *p.x(), it's not very clean and I'd expect some added overhead. One could go even uglier and make x, y, and z be instances of some custom class with overridden operators that reference arr[], but that seems like it'd be just getting ridiculous in terms of overhead (both coding and performance)
Last edited on
> you can't call them like p.x,

What's so difficult about calling them like p.x() ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct point
{
    point( float x, float y, float z ) : arr{ x, y, z } {}

    point& assign( float xx, float yy, float zz )
    {
          x() = xx ;
          y() = yy ;
          z() = zz ;
          return *this ;
    }

    private:
        std::vector<float> arr {0,0,0} ; 

        float& x() { /* if( arr.empty() ) throw std::out_of_range("") ; */ return arr[0] ; }
        float& y() { return arr[1] ; }
        float& z() { return arr[2] ; }

        float x() const { return arr[0] ; }
        float y() const { return arr[1] ; }
        float z() const { return arr[2] ; }
};
What's so difficult about x.sum(y) instead of x += y? C++ provides tools for you to keep your code cleaner. I'm asking whether it's possible to keep this clean. With C-style aligned variables and pointers one can keep it clean, so it'd be a shame if using std means having to make it uglier.
provides tools for you to keep your code cleaner
For example ability to separate implementation from interface, so changes to implementation will not break all code using this class.
whether it's possible to keep this clean
point.x() += point.y() /*vs*/ point.x += point.y? Are four characters completely breaks readability and make code unclean. If so, we haver different vision of unreadable code
With C-style aligned variables and pointers one can keep it clean bug-ridden mess
What's so difficult about x.sum(y) instead of x += y?
Ask Google. I think they have an answer.
/sarcasm


If you insist:
1
2
3
4
5
6
7
8
9
10
11
struct point
{
    point( float x_, float y_, float z_ ) : arr{ x_, y_, z_ } {}

    //bad style. You should not expose data to the users directly
    //Separate interface and implementation
    float& x = arr[0];
    float& y = arr[1];
    float& z = arr[2];
    std::array<float, 3> arr {{0.0, 0.0 , 0.0}};
};
"What's so difficult about x.sum(y) instead of x += y? "

Are you sure you want to be on a C++ forum and not a C forum? If operator overloading is such a crazy concept to you...

Do you seriously think x.sum(y) is as quickly readable and understandable as x += y?

"For example ability to separate implementation from interface"

Exactly. Implementation like "arr[0]", called by assigning to or reading from x. The alternative is #define. Sound like a better option to you?

You do realize that there's often tons of stuff in stl that goes on behind the scenes when you make what appears to be simple assignments, right? I'm wanting to have my own behind the scenes code for precisely the same reason. If you have an object that's used a lot, it's far more important to have its interface used by the other parts of code appear nice and simple even if it means the object itself is more complicated.

I know ways I can do this. As mentioned, I could create a subclass that defines operator() float and a copy constructor. But there's a number of side cases that could complicate it, so I'm wondering if there's a simpler way.
Last edited on
Topic archived. No new replies allowed.