2

So I've been looking at some stuff and found this thread Aliasing struct and array the C++ way

And this is the answer to the question

#include <math.h>

struct Point {
    double x;
    double y;
    double z;
};

double dist(struct Point *p1, struct Point *p2) {
    constexpr double Point::* coords[3] = {&Point::x, &Point::y, &Point::z};

    double d2 = 0;
    for (int i=0; i<3; i++) {
        double d = p1->*coords[i] - p2->*coords[i];
        d2 += d * d;
    }
    return sqrt(d2);
}

Now my problem is that I have no idea what

constexpr double Point::* coords[3] = {&Point::x, &Point::y, &Point::z};

is supposed to do...

I understand that constexpr makes it a constant that is defined at compile time and double is obviously used because the struct contains doubles but the Point::* and the {&Point::x, &Point::y, &Point::z}; confuse me. First of all what is Point::*? I guess the * means it is a some kind of pointer but to what? And what are these addresses {&Point::x, &Point::y, &Point::z} ?

What exactly does this entire expression define?

Marko Borković
  • 1,884
  • 1
  • 7
  • 22

1 Answers1

1

This syntax is a pointer to member, and is essentially a way to store a member to a variable and retrieve it. It's useful for a case like this, when you want to loop through a list of members.

Aplet123
  • 33,825
  • 1
  • 29
  • 55
  • 1
    You say “useful for a case like this” but I find this specific usage highly dubious. It’s longer than the “manual” code, uses more layers of indirection, is less readable, and isn’t even more efficient (without testing it I believe the compiler will be able to unroll the loop and inline the variable access, but by doing so all it does is draw even with the manual version). – Konrad Rudolph Aug 06 '20 at 14:07
  • First off, using a range for loop, the code would look a lot nicer. Second, because the array is constexpr, you could supply any array via a template argument. This means having one function for vec2, vec3 and vec4, while also having the function as a whole be constexpr, which surely helps. But this would never be used in a vector math library, because it might have problems with SSE optimisation. – DexterHaxxor Feb 13 '21 at 13:35