2010-01-16 54 views
2

我的问题与一个this有关。模板定义中的朋友函数

我想重载操作< <一些类和我发现了两个不同的符号,这两个工作:

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); 
}; 

难道我定义具有不同的符号一样的东西?或者是第一个更严格的版本,在哪个实例中(在这种情况下,只有与我的A类相同T的实例)< <是A的朋友?

回答

1

第一个版本限制了友谊的operator<<为特定类型的A<T>,而第二句接受一个A<SomeType>朋友任何operator<<

所以,是的,第一个是更严格:

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; 
} 
+0

几件事。首先,我认为你的意思是'os << b.t'而不是'os << b.i'来输出拥有的成员变量。其次,上面的例子可以使用operator << instance,因为它使用的是'ostreame&operator <<(ostream&os,double num)'函数,而不是声明的模板版本。 – workmad3 2010-01-16 10:03:35

+0

我的头似乎在其他地方 - 但在平均时间修复它。 – 2010-01-16 10:04:48

0

恰巧,友元函数的定义有模板例外。它允许你这样写:

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 
    } 
}; 

而且它具有为您创建的A<T>每个实例自动创建一个正常功能的优势。

仅供参考:http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16

+0

你的意思是“异常”,你不必在运算符的定义中写A ? 我的问题:它真的有优势吗?好的,你没有模板版本的<<,但在上面的情况下,还为<<创建模板的实例,如果它在某个特定的类中使用。 – haselhorstk 2010-01-16 11:16:23

+0

主要优点是你不需要前向声明......但是你必须总是在每个类中定义它。 – 2010-01-16 11:29:22

+0

真正的优势在于您根本没有定义函数模板!所以你没有任何相关的问题,比如强制。 – PierreBdR 2010-01-17 18:15:07