2012-05-28 108 views
4

我有一個問題重載<<流運算符,我沒有找到解決辦法:C++:friend聲明「聲明一個非模板函數

template<class T, unsigned int TN> 
class NVector 
{ 
    inline friend std::ostream& operator<< (
     std::ostream &lhs, const NVector<T, TN> &rhs); 
}; 

template<class T, unsigned int TN> 
inline std::ostream& NVector<T, TN>::operator<<(
    std::ostream &lhs, const NVector<T, TN> &rhs) 
{ 
    /* SOMETHING */ 
    return lhs; 
}; 

它產生以下錯誤消息:

warning : friend declaration ‘std::ostream& operator<<(std::ostream&, const NVector&)’ declares a non-template function [-Wnon-template-friend]

error: ‘std::ostream& NVector::operator<<(std::ostream&, const NVector&)’ must take exactly one argument

如何解決這個問題?

非常感謝。

+0

一位朋友不是會員,'operator <<'不應該是會員。刪除定義標題中的分辨率。 – chris

回答

10

代碼中有兩個不同的問題,第一個是friend聲明(正如警告中明確指出的,可能不那麼明白)可以聲明一個單獨的非模板函數作爲朋友。也就是說,當您實例化模板NVector<int,5>時,它將非模板功能std::ostream& operator<<(std::ostream&,NVector<int,5>)聲明爲朋友。請注意,這與聲明您作爲朋友提供的模板函數不同。

我建議您在類定義中定義好友功能。您可以在answer中閱讀更多內容。

template <typename T, unsigned int TN> 
class NVector { 
    friend std::ostream& operator<<(std::ostream& o, NVector const & v) { 
     // code goes here 
     return o; 
    } 
}; 

或者你可以選擇其它選項:

  1. 聲明operator<<模板作爲朋友(將授予訪問任何與該模板的所有實例),
  2. 聲明的特定實例作爲朋友的模板(寫起來更麻煩)或
  3. 避免友誼共享print(std::ostream&)成員函數並從非朋友模板operator<<中調用它。我仍然會選擇接受非模板函數,並在模板類中提供定義。

的第二個問題是,當你要定義的類左側的說法之外的運營商,運營商是免費功能(未綁定到一個類),因此它不應該是合格:

template<class T, unsigned int TN> 
inline std::ostream& operator<<(std::ostream &lhs, const NVector<T, TN> &rhs) 
{ 
    /* SOMETHING */ 
    return lhs; 
};