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?

Community
  • 1
  • 1
haselhorstk
  • 169
  • 1
  • 1
  • 7

2 Answers2

1

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
  • 97,545
  • 26
  • 194
  • 236
  • Couple of things. First, I think you meant 'os << b.t' rather than 'os << b.i' to output the owned member variable. Second, the above example would work fine with either operator << instance as it would be using the 'ostreame& operator<< (ostream& os, double num)' function, not the declared template version. – workmad3 Jan 16 '10 at 10:03
  • I had my head somewhere else it seems - but fixed it in the mean-time. – Georg Fritzsche Jan 16 '10 at 10:04
0

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
  • 42,120
  • 10
  • 46
  • 62
  • with "exception" you mean, that you don't have to write A 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 Jan 16 '10 at 11:16
  • 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 Jan 16 '10 at 11:29
  • 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 Jan 17 '10 at 18:15