Template Friending syntax
c++, templates
Solution
Befriending all possible specializations of `baseclass2<D>::foo` is rather easy:
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&);
};
Live example.
A forward 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 out-of-class definitions for function templates of class templates. :)
Befriending specifically `baseclass2<D>::foo<T>` is not possible, however, or I can't find the correct syntax for it.
A workaround might be some global function that forwards the access and together with the passkey pattern, but meh, it's 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); }
};
Live example.
Problem
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 friend all types of `baseclass2`, a many-to-many relationship. I have two questions, What is the syntax to allow baseclass1 to friend just the function ``` baseclass2<class D>::foo<class T>( D& x, T& y). ``` And, what is the syntax to allow `baseclass1` to friend just the function `baseclass2<class D>::foo<class T>( D& x, T& y)` where `T` from `baseclass1` matches The `T` from Function `foo`. EDIT To those who keep claiming you can't friend a template specialization. This code works ``` template<class cake> class foo { public: static void bar(cake x) { cout << x.x; } }; 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 where muffin friends the wrong foo, and still causes a compilation error. This works with both functions and classes. I am totally willing to accept that this isn't possible in my specific situation (It's actually looking more and more that way) I'd just like to understand why.