Making friends with all of the possible baseclass2<D>::foo specializations is quite simple:
template<class T> class baseclass1; template<class D> class baseclass2{ public: template<class T> void foo(D&, T&){ baseclass1<T> x; x.priv_foo(); } }; template<class T> class baseclass1{ template<class D> template<class U> friend void baseclass2<D>::foo(D&, U&); void priv_foo(){} }; template<class T> class baseclass1{ template<class D> template<class U> friend void baseclass2<D>::foo(D&, U&); };
Real-time example.
A portable declaration of baseclass2 (so baseclass1 knows that baseclass2 exists and is a template) and two templates: one for the class, one for the function. It also looks like this for defining outside the class for function templates of class templates. :)
To make friends specifically with baseclass2<D>::foo<T> impossible, however, or I cannot find the correct syntax for it.
The workaround may be some global function that redirects access along with the passkey template , but meh, this is a mess (imho):
template<class D> class baseclass2; template<class D, class T> void baseclass2_foo(baseclass2<D>& b, D&, T&); template<class D, class T> class baseclass2_foo_key{ baseclass2_foo_key(){} // private ctor friend void baseclass2_foo<>(baseclass2<D>&, D&, T&); }; template<class T> class baseclass1{ public: // public access, but only baseclass2_foo can create the key template<class D> void priv_foo(baseclass2_foo_key<D, T> const&){} }; template<class D, class T> void baseclass2_foo(baseclass2<D>&, D&, T&){ baseclass1<T> x; x.priv_foo(baseclass2_foo_key<D, T>()); } template<class D> class baseclass2{ public: template<class T> void foo(D& d, T& t){ baseclass2_foo(*this, d, t); } };
Real-time example.
Xeo
source share