C++ template-based friend operators

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16 describes two ways of solving the "call to non-template" error. This error gets thrown when one defines a template class with some friend operator(s) declared in a natural manner, not thinking that declaring the template friend(s) like this will resolve the method into a non-template one. I find the first method of pre-declaring the operator to be tiresome and the second i say it can make the class definition unreadable if the operator definition is complex. I'm going to choose a third way of defining template friends:

template <typename T>
class C
  template <typename T1> friend istream& operator>>(istream &, C<T1>&);

altho this can be a little bit hard to understand at first sight because of different template parameter name

update: example for jamie

#include <iostream>

using namespace std;

//we define 
//the ostream operator the parashift's way 
//and the istream operator deadloop's way
//ostream operator related code
template<typename T> class A;
template<typename T> ostream& operator<< (ostream &os, const A<T>& a) throw();
//for istream we don't need to predeclare anything

template<typename T>
class A
  template <typename T1> A(T1 value) throw();
  virtual ~A();
  //this is deadloop's istream operator, i don't need to convince the
  //compiler of anything
  template <typename T1> friend istream& operator>> (istream &is, A<T1>& a) throw();
  //and the parashift's way
  friend ostream& operator<< <> (ostream &os, const A<T>& si) throw();
  T data;

template <typename T> A<T>::A() {}
template <typename T> A<T>::~A() {}
template <typename T> istream& operator>> (istream &is, A<T> &a) throw()
template <typename T> ostream& operator<< (ostream &os, const A<T>& a) throw()

  return os<<a.data;

int main(int argc, char **argv)
  A<int> ob;
  cout<<"enter an integer for A<int>: ";
  cin >>ob;
  cout << "object's data is: " << ob << endl;
  return 0;


  1. doesn't work for me ... i get error: `std::ostream& operator>>(std::ostream&)' must take exactly two arguments. :-( i'd love to see an elegant way of friend'ing a ostream operator in a template class that compiles without doing it outside the class.

  2. okay, my bad ... i reviewed the code and found i forgot to comma separate the parameters ... still doesn't compile. i get "undefined reference to `std::basic_ostream >& operator<< , std::allocator > >(std::basic_ostream >&, set, std::allocator > >&)'
    collect2: ld returned 1 exit status"

    called like this in main():

    set s;

    std::cout << s;


  3. sup jamie,

    i didn't expect any comments on my posts. sorry for not answering.
    i updated the post with an example for you.