2015-01-11 70 views
1

我想超載< <運營商和使用好友功能。 下面的代碼塊工作得很好。嘗試超載時出錯<<運營商和使用好友功能

template <class T> 
class Mystack{ 
    friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d) 
    { 
     d.print(s); 
     return s; 
    } 
}; 

因爲它是朋友函數,我顯然想要在類之外定義它,而不使用範圍解析運算符。但是,當我嘗試我得到錯誤。

template <class T> 
class Mystack{ 
    friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d); 
}; 
template <class T> 
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d) 
{ 
    d.print(s); 
    return s; 
} 

下面是主要

Mystack<int> intstack; 
std::cout << intstack; 

錯誤代碼片段:未解決extrernal符號。

P.S:它不是完整的運行代碼。只是一個樣本。請忍受。

+0

'class sample {'shouldnt that'class Mystack'? – Borgleader

+0

哎呀我的壞! – tanz

+2

當涉及到模板時,只需將所有內容放在頭文件中。這不值得頭痛。 –

回答

4
friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d); 

聲明和結識非模板operator<<函數。所以Mystack<int>將作爲它的朋友非模板函數std::ostream& operator<<(std::ostream& s, Mystack<int> const& d);

template<class T> 
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d) 
{ 
    d.print(s); 
    return s; 
} 

定義operator<<函數模板。

兩者不一樣。當您編寫std::cout << intstack;時,重載解析規則會將其解析爲您聲明的非模板operator<<函數,但它未定義,因此會出現鏈接器錯誤。

沒有辦法爲類模板外的類模板的每個實例定義非模板函數。你可以,但是,善待你的operator<<函數模板的特化:

// forward declarations 
template <class T> 
class Mystack; 
template <class T> 
std::ostream& operator<<(std::ostream& s, Mystack<T> const& d); 

template <class T> 
class Mystack 
{ 
    friend std::ostream& operator<< <T>(std::ostream& s, Mystack<T> const& d); 
//         ^^^ 
}; 

或交好函數模板,這是從一個角度封裝點(因爲糟糕的是,每一個專業化例如,operator<< <int>是朋友Mystack<float>):

template <class T> 
class Mystack 
{ 
public: 
    template <class U> 
    friend std::ostream& operator<<(std::ostream& s, Mystack<U> const& d); 
}; 

或者只是在類中定義好友功能。

+0

如果我從函數中刪除'template ',該怎麼辦?那麼我也會得到錯誤。 – tanz

+0

@tanz正如在,只是'std :: ostream&operator <<(std :: ostream&s,Mystack const&d)'?那麼你不能使用'T'。 –

+0

ya ... true .. :( – tanz