我試圖提高對模板的理解。作爲一個測試,我想過載流operator<<
,以便它將與STL中的(模板化的)basic_ostream
一起在模板類上運行。下面是一個小例子:正確地聲明模板運算符<<(basic_ostream <charT,traits>,myClass < T >)爲朋友
#include <iostream>
using namespace std;
//Forward declarations
template< typename T >
class Container;
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<(basic_ostream< charT, traits >& out,
const Container<T>& a_container);
//Definitions
template< typename T >
class Container
{
public:
Container(T a_value): value(a_value){}
private:
T value;
template< typename charT, typename traits >
friend basic_ostream< charT, traits >&
operator<<(basic_ostream< charT, traits >& out,
const Container<T>& a_container);
};
template< typename T, typename charT, typename traits >
basic_ostream< charT, traits >&
operator<<(basic_ostream< charT, traits >& out,
const Container<T>& a_container)
{
out << a_container.value;
return out;
}
//Main
int main(void)
{
Container<int> my_container(42);
cout << my_container;
return 0;
}
然而,當我嘗試編譯此代碼似乎鏈接器無法找到重載函數:
/home/Ae6PGM/cc5xj2iM.o: In function `main':
prog.cpp:(.text.startup+0x21): undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <char, std::char_traits<char> >
(std::basic_ostream<char, std::char_traits<char> >&, Container<int> const&)'
collect2: error: ld returned 1 exit status
我可以修復這個錯誤,如果我做每一個模板實例我的超載operator<<
的朋友,但如果只有與容器類型匹配的實例是朋友,那麼它似乎更正確。這是一個鏈接到工作,但不正確的verion:http://ideone.com/DNQzlB。
另一種選擇是將函數定義放在類聲明中,但是如果可能的話,我想避免這種情況。
有一個類似的,但稍微簡單的問題here。有一個很好的答案,但我無法弄清楚如何適應我的問題。
感謝,
安德魯
我開始認爲這是不可能的,因爲它要依賴於未在C++支持的部分專用函數模板。那是對的嗎? –
我想這裏的答案可能會有所幫助:http://stackoverflow.com/questions/1458752/template-friendship –
'boost'庫定義了類中的這種類型的朋友函數。請參閱:http://www.boost.org/doc/libs/1_55_0/boost/random/poisson_distribution.hpp –