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?
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.