views:

137

answers:

2

My question ist related a bit to this one.

I want to overload the operator << for some class and I found two different notations that both work:

template <class T>
class A{
  T t;
public:
  A(T init) : t(init){}
  friend ostream& operator<< <> (ostream &os, const A<T> &a); //need forward declaration
  //template <class U> friend ostream& operator<< (ostream &os, const A<U> &a);
};

Do I define identical things with different notations? Or is the first version more restrictive in which instance (in this case only the instance with the same T as my class A) of << is friend of A?

+2  A: 

The first version restricts the friendship to the operator<< for the specific type A<T> , while the second makes any operator<< that takes an A<SomeType> a friend.

So yes, the first one is more restrictive:

template<class T>
ostream& operator<< (ostream& os, const A<T>& a) {
    A<double> b(0.0);
    b.t; // compile error with version 1, fine with version 2
    return os;
}

int main() {
    A<int> a(0);
    cout << a << endl;
}
Georg Fritzsche
workmad3
I had my head somewhere else it seems - but fixed it in the mean-time.
Georg Fritzsche
A: 

It so happens that the definition of friend functions have an exception for templates. It allows you to write this:

template <class T>
class A{
  T t;
public:
  A(T init) : t(init){}
  friend ostream& operator<<(ostream &os, const A &a)
  {  // Implementation in the class
  }
};

And it has the advantage of creating a normal function automatically created for each instance of A<T> you create.

For reference: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16

PierreBdR
with "exception" you mean, that you don't have to write A<T> in the definition of the operator?My question: is it really an advantage? Ok, you don't have the template version of <<, but in the cases above there is also created an instance of the template for << if it is used somewhere with a specific class.
haselhorstk
The main advantage would be that you don't need the forward declarations... you have to always define it in every class then though.
Georg Fritzsche
The real advantage is that you don't define a function template at all! So you don't have any of the associated problem, like with coercion.
PierreBdR