2012-07-30 97 views
5

什麼是聲明一個模板類的友元函數的正確方法(爲的std :: ostream的&操作< <)在.cpp文件C++:在模板類運營商友元函數<<

我當前的實現不工作:

// MyTest.h 
template<class T, unsigned int TSIZE> class MyTest 
{ 
    inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs); 
}; 

// MyTest.cpp 
template<class T, unsigned int TSIZE> inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

非常感謝您!

+0

你究竟是什麼意思的「不工作」......編譯器錯誤?哪些錯誤?首先猜測...「朋友」不屬於.cpp版本。 – 2012-07-30 04:37:35

回答

7

要像你一樣引用operator<< <T, TSIZE>這是一個模板專業化,主模板的聲明必須是可見的。反過來,operator<<需要聲明MyTest,因爲它作爲參數出現。

// Declare MyTest because operator<< needs it 
template<class T, unsigned int TSIZE> class MyTest; 

// Declare primary template 
template<class T, unsigned int TSIZE> 
inline std::ostream& operator<<(std::ostream& lhs, const MyText<T, TSIZE>& rhs); 

template<class T, unsigned int TSIZE> class MyTest 
{ 
    // Specialization MyTest<T, TSIZE> only declares 
    // specialization operator<< <T, TSIZE> as friend 
    // Note that you can just use '<>' to designate the specialization, 
    // template parameters are deduced from the argument list in this case 
    inline friend std::ostream& operator<< <> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs); 
}; 

您的定義應該與這些聲明相匹配。請注意,因爲operator<<是一個模板,所以它的定義應該很有可能在標題中。

當談到編寫所有這些先發制人的聲明時,需要較少工作的替代方案是MyTest<T, TSIZE>將整個模板聲明爲朋友,而不僅僅是需要MyTest<T, TSIZE>的專業化。

// in MyTest definition 
template<typename U, unsigned USIZE> 
inline friend std::ostream& operator<<(std::ostream& lhs, const MyTest<U, USIZE>& rhs); 

你必須定義也應該符合這樣的聲明(模板參數的名稱有匹配的聲明和定義沒有關係)。

爲了完整起見,我會提到,當談到類模板的朋友時,另一種方法是在類模板定義中定義它。這爲每個專業化定義了一個非模板的朋友函數。

// in MyTest definition 
friend std::ostream& operator<<(std::ostream& lhs, MyTest const& rhs) 
{ /* implementation */ } 

這是不可能將此類功能(例如&ns::operator<<不起作用,不像其他選項),並且它們僅通過ADL找到。

0

這並不完全清楚原來的帖子想要什麼。我會認爲它希望以下內容:

// Some template class. 
template<class T, unsigned int TSIZE> class MyTest { }; 

// Some template function. 
template<class T, unsigned int TSIZE> std::ostream& operator<< (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

現在是需要聲明這個模板函數作爲類的朋友,因爲這個功能需要訪問的My test保護對象。這可以用下面的定義來實現:需要在friend聲明的前

template<class T, unsigned int TSIZE> class MyTest 
{ 
    template<class T1, unsigned int TSIZE1> 
    friend std::ostream& operator<< (std::ostream &lhs, const MyTest<T1, TSIZE1> &rhs); 
}; 

模板頭,因爲這是一個不相關的模板函數,不屬於當前模板類。