2

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: http://bloglitb.blogspot.de/2011/12/access-to-private-members-safer.html

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

I wondered if this very elegant approach can be reused to access private methods from outside of a class.

What I would like to have, is the same simple approach for a method call:

struct A_access_f
{
    typedef int (A::*type)();
    friend type get(A_access_f);
};
template struct Rob<A_access_f, &A::f>;

Is it possible to make it run?

This is my best attempt till now:

typedef int (A::*pf)();
pf func = sut.*get(A_access_f());

My compiler is still complaining:

prog.cpp:45:33: error: invalid use of non-static member function pf func = sut.*get(A_access_f());

Community
  • 1
  • 1
mrAtari
  • 620
  • 5
  • 17

1 Answers1

1

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()))();
Leon
  • 31,443
  • 4
  • 72
  • 97
  • Interesting, I was playing around with the one-liner style too, but suffered with the correct syntax. – mrAtari Sep 23 '16 at 11:23