cppreference and Johannes Schaub - litb both provide the same method for getting this to work.
You want to make one single instance (called "specialization" in generic terms) of that template a friend. You do it the following way [...]
First make a forward declaration before the definition of your class:
template <class K, class T> class KeyedCollection;
template<class K, class T>
ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst);
Because the compiler knows from the parameter list that the template arguments are T and U, you don't have to put those between <...>, so they can be left empty.
Then make your friend declaration and be sure to add <>
after operator<<
:
template <class K, class T>
class KeyedCollection {
public:
// snip
friend ostream& operator<< <> (ostream& outstream,const KeyedCollection<K,T>& inst);
// snip
};
Finally you can define it:
template<class K, class T>
ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst) {
// Just an example
for (const auto& t : inst.objects)
{
std::cout << t << std::endl;
}
return outstream;
}
Alternately, do what Yakk suggested.
template <class K, class T>
class KeyedCollection {
public:
// snip
friend ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst) {
for (const auto& t : inst.objects)
{
std::cout << t << std::endl;
}
return outstream;
}
// snip
};