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 diff开发者_运维技巧erent 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?
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;
}
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
精彩评论