Although I completely agree with me22 that you should use std::list and if you
do have good reason not to use std::list that your overloaded insertion operator should not need to be a friend, for reference here is how you would make it a friend if you really needed to:
#include <iostream>namespace dust{ // forward declaration of list class needed for following forward declaration template < class T > class list; // forward declaration of insertion operator needed to declare a specific template friend template < class T > std::ostream & operator<<(std::ostream & os, list< T > const & obj); template <class T> class list { struct node { node * next; T value; }; node * head; node * tail; // note the additional <> which indicates that the friend is a template function friend std::ostream & operator<<<>(std::ostream & os, list< T > const & obj); }; template<class T> std::ostream & operator<<(std::ostream & os, list< T > const & obj) { os << "["; typename list< T >::node * node; for (node = obj.head; node != obj.tail; node = node->next) { os << node->value << " "; } node = node->next; os << node->value << "]"; return os; }}int main(){ dust::list<int> a; std::cout << a << std::endl;}
Note that this is not equivalent to the friend declaration template < typename T > friend std::ostream & operator<<(std::ostream & os, list< T > const & obj);, which makes
all list insertion operators friends of
all list template instantiations (i.e. operator<<(std::ostream &, list< int >) would be able to access private members of list< double >).
Enigma