Disclaimer: This is never meant to be used in production code. It's an exploration at the edges of C++ :)
My question is a follow up, based on a discussion with @Johannes Schaub here:
calling private methods in c++.
I found a very short solution for private member access on his blog:
Here's a sample:
#include <iostream>
using namespace std;
// example class
struct A {
A(int a, double b):_a(a),_b(b) { }
private:
int _a;
double _b;
int f() { return _a; }
public:
};
//Robber template: provides a legal way to access a member
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// tag used to access A::_a
struct A_access_a
{
typedef int A::*type;
friend type get(A_access_a);
};
// Explicit instantiation; the only place where it is legal to pass the address of a private member.
template struct Rob<A_access_a, &A::_a>;
int main() {
A sut(42, 2.2);
int a = sut.*get(A_access_a());
cout << a << endl;
return 0;
}
struct A_access_f
{
typedef int (A::*type)();
friend type get(A_access_f);
};
template struct Rob<A_access_f, &A::f>;
typedef int (A::*pf)();
pf func = sut.*get(A_access_f());
prog.cpp:45:33: error: invalid use of non-static member function
pf func = sut.*get(A_access_f());
You were almost there. Here is what you should have written:
typedef int (A::*pf)(); const pf func = get(A_access_f()); int a = (sut.*func)();
Or as a (hard-to-digest) one-liner:
int a = (sut.*get(A_access_f()))();