Aliasing struct and array the C++ way Aliasing struct and array the C++ way arrays arrays

Aliasing struct and array the C++ way


Use an constexpr array of pointer-to-member:

#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);}


IMHO the easiest way is to just implement operator[]. You can make a helper array like this or just create a switch...

struct Point{    double const& operator[] (std::size_t i) const     {        const std::array coords {&x, &y, &z};        return *coords[i];    }    double& operator[] (std::size_t i)     {        const std::array coords {&x, &y, &z};        return *coords[i];    }    double x;    double y;    double z;};int main() {    Point p {1, 2, 3};    std::cout << p[2] - p[1];    return 0;}


struct Point {  double x;  double y;  double z;  double& operator[]( std::size_t i ) {    auto self = reinterpret_cast<uintptr_t>( this );    auto v = self+i*sizeof(double);    return *reinterpret_cast<double*>(v);  }  double const& operator[]( std::size_t i ) const {    auto self = reinterpret_cast<uintptr_t>( this );    auto v = self+i*sizeof(double);    return *reinterpret_cast<double const*>(v);  }};

this relies on there being no packing between the doubles in your `struct. Asserting that is difficult.

A POD struct is a sequence of bytes guaranteed.

A compiler should be able to compile [] down to the same instructions (or lack thereof) as a raw array access or pointer arithmetic. There may be some problems where this optimization happens "too late" for other optimzations to occur, so double-check in performance sensitive code.

It is possible that converting to char* or std::byte* insted of uintptr_t would be valid, but there is a core issue about if pointer arithmetic is permitted in this case.