Friendly Template Syntax

Say I have two Template classes.

template<class T> class baseclass1 { template<class> friend class baseclass2; } template<class D> class baseclass2 { template<class T> void foo( D& x, T& y) { ... } } 

The above code allows all types of baseclass1 to be friends with all types of baseclass2 , many-to-many relationships. I have two questions:

What is the syntax that allows baseclass1 to be friends only with a function

 baseclass2<class D>::foo<class T>( D& x, T& y). 

And what is the syntax that allows baseclass1 be friends only with a function

baseclass2<class D>::foo<class T>( D& x, T& y) where T from baseclass1 matches T from the function foo .

EDIT

For those who continue to argue, you cannot find the template specialization. This code works

 template<class cake> class foo { public: static void bar(cake x) { cout << xx; } }; class pie { public: void set( int y){ x = y; } private: int x; friend void foo<pie>::bar(pie x); }; class muffin { public: void set( int y){ x = y; } private: int x; friend void foo<pie>::bar(pie x); }; int main { pie x; x.set(5); foo<pie>::bar(x); muffin y; y.set(5); //foo<muffin>::foo(y); //Causes a compilation Error because I only friended the pie specialization } 

Even notice that cupcake friends are wrong, and still cause a compilation error. This works with both functions and classes. I completely agree that this is not possible in my specific situation (in fact, it looks more and more). I just wanted to understand why.

+8
c ++ templates
source share
2 answers

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.

+2
source share

AFAIK, you can specify all instances of foo as friend, but not specific instances:

 template< class T > class C1 { public: template< class Q > void foo( T& x, Q& y ) { } }; template< class T > class C2 { template< class Y > template< class Q > friend void C1<Y>::foo( Y&, Q& ); }; 
0
source share

All Articles