正如Igor Tandetnik指出的那樣,您的示例聲明瞭一個非模板的朋友函數,您必須爲每個模板實例化重載,這是允許朋友函數內聯定義的一個原因(因此可以生成它們通過模板本身而不必是模板)。
如果要定義友元函數爲模板,這裏是我能夠拿出最接近:
template <typename T>
struct Outer {
template <typename U>
struct Inner;
};
template<typename T, typename U>
bool operator==(typename Outer<T>::template Inner<U> const &, typename Outer<T>::template Inner<U> const &);
template <typename T>
template <typename U>
struct Outer<T>::Inner {
friend bool operator==<T,U>(Inner const &, Inner const &);
};
template<typename T, typename U>
bool operator==(typename Outer<T>::template Inner<U> const &, typename Outer<T>::template Inner<U> const &) {
return true;
}
// I switched this out, because my gcc-4.6 doesn't
// understand "using" aliases like this yet:
typedef Outer<int>::Inner<short> Type;
int main() {
Type a;
Type b;
operator==<int,short>(a, b);
}
不幸的是,你會發現這個操作符函數的調用網站是非常尷尬:operator==<int,short>(a, b)
。我相信在這樣的嵌套類模板上定義一個函數模板會禁用(或者至少干擾)參數推導,所以你必須顯式地指定模板參數(這意味着將其作爲一個函數而不是以運算符形式進行調用)。這就是爲什麼內聯朋友定義非常方便。如果你真的想單獨定義你的operator==
的代碼,我建議定義內聯的friend
以調用另一個函數模板(使用適當的模板參數),然後可以將其作爲一個自由函數進行異步定義。
嗯,這是一個非常好的解釋,我現在將決定使用內聯定義,但會牢記您的建議。 – Lyberta