2010-01-16 92 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