Another C++ crazyness

Content:

I saw something on LinkedIn, but I changed the code quite a bit.

Everybody knows private members can only be accessed from the class itself. Right?

#include <iostream>

using namespace std;

class Data
{
private:
    int v;
public:
    void SetV(int v);
    int GetV();
};

void Data::SetV(int v)
{
    cout << "SetV called" << endl;
    this->v = v;
}

int Data::GetV()
{
    return this->v;
}

// ****
template<int Data::*ptr>
struct Steal
{
    friend void hack(Data& o, int v)
    {
        o.*ptr = v;
    }
};

template class Steal<&Data::v>;

void hack(Data& o, int v);
// ****

int main()
{
    Data o;
    o.SetV(123);
    cout << o.GetV() << endl;
    // error:
    // o.v = 456;
    // no error:
    hack(o, 456);
    cout << o.GetV() << endl;
    return 0;
}
    

Output:

SetV called
123
456

WTF. Probably not something anybody intended, but somewhere in the complexity of C++ language rules this become possible.

Comments: