1

I am writing a template class that takes both a class and the name of a method within that class. I have to do this because even though the various classes that I will use to instantiate my template have similar methods with a common signature that method's name varies from class to class. In some cases the method in question is private. Hence I would like to augment such classes with a friend declaration granting my template access to the private method.

template<class T, int (T::*func)()>
class A {
  public:
    int count(T* p) { return (p->*func)(); }
};

class B {
  public:
    int funcPublic() { return 0; }
};

class C {
    template<class T, int (T::*)()> friend class A;
  private:
    int funcPrivate() { return 0; }
};

typedef A<B, &B::funcPublic > AB;  // works
typedef A<C, &C::funcPrivate> AC;  // g++:  "error: ‘int C::funcPrivate()’ is private"

Access control seems to be checked at the point of mention (i.e. template instantiation) rather than at the point of use. Is this how C++ is specified? Am I simply out of luck?

John Yates
  • 1,027
  • 1
  • 7
  • 18
  • Related (but using pointer-to-member-variable, not member-function): http://stackoverflow.com/a/3173080/103167 – Ben Voigt Apr 14 '16 at 23:13
  • 2
    You are wiling to make `A` a friend of all of these classes, but you are not willing to implement a common interface for `A` to invoke? Seems like an odd requirement... You might get some useful feedback if you explain what you are actually trying to do. – Nemo Apr 14 '16 at 23:14
  • @BenVoigt: At the point I needed to write code like that, I would assume my design was probably wrong. – Nemo Apr 14 '16 at 23:16

1 Answers1

2

If you can modify your class C, it seems that you can work around it as follows:

class C 
{
private:
    int funcPrivate() { return 0; }

public:
    typedef A<C, &C::funcPrivate> value;
};

typedef C::value AC;

By this approach, you don't really have to augment such classes with friend also.

However, if that approach satisfies your requirement, please consider providing a proper interface to invoke the method.

Dean Seo
  • 5,486
  • 3
  • 30
  • 49