There are three kinds of friend declarations that may appear within a class template:
class Foo {
public:
void bar();
};
template <class T>
class QueueItem {
friend class foobar;
friend void foo();
// It grants Foo::bar() access to the private/protected members of
// the specific instantiation of the class QueueItem<T>.
friend void Foo::bar();
// ...
};
The class foobar and the function foo() do not have to be declared or defined in global scope before the class template QueueItem declares them as friends. However, the class Foo must be defined before the class QueueItem can declare one of its members as a friend.
QueueItem and its friends, also template instantiations.
#include <iostream>
template <typename T> class Helper;
template <typename T> class MyClass;
template <typename T> void foo(MyClass<T>&);
template <class T>
class Helper2 {
public:
void reveal2( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
};
template<class T>
class MyClass {
// function template
friend void foo<T>( MyClass<T>& );
// class template
friend class Helper<T>;
// member function template
friend void Helper2<T>::reveal2( MyClass<T>& );
public:
MyClass(T m) : _m(m){}
private:
T _m;
};
template<class T>
class Helper {
public:
void reveal( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
};
template<class T>
void foo( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
int main(){
MyClass<int> cl(1);
foo(cl);
Helper<int> hi;
hi.reveal(cl);
Helper2<int> hi2;
hi2.reveal2(cl);
return 0;
}
QueueItem and the friend.
#include <iostream>
template <typename T> class Helper;
template <typename T> class MyClass;
template <typename T> void foo(MyClass<T>&);
template <class T>
class Helper2 {
public:
void reveal2( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
};
template<class T>
class MyClass {
// function template
template <class U>
friend void foo( MyClass<U>& );
// class template
template <class U>
friend class Helper;
// member function template
template <class U>
friend void Helper2<U>::reveal2( MyClass<U>& );
public:
MyClass(T m) : _m(m){}
private:
T _m;
};
template<class T>
class Helper {
public:
void reveal( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
};
template<class T>
void foo( MyClass<T>& obj ){
std::cout << obj._m << "\n";
}
int main(){
MyClass<int> cli(1);
MyClass<double> cld(1.2);
foo(cli);
foo(cld);
Helper<double> hi;
hi.reveal(cld);
Helper2<int> hi2;
hi2.reveal2(cli);
return 0;
}