template
class Mat {
friend Mat operator+(Mat& m, T num); // 連結錯誤:LNK2001 無法解析的外部符號
};
編譯通過,連結失敗。原因:編譯器無法識別這是模板函式,將其視為非模板函式,導致實例化缺失。
template
class A {
friend void func(); // 普通函式,可存取所有 A 實例
};
template
class A {
template
friend void func(U u); // func 可存取所有 A 實例,U 與 T 無關
};
template
class A {
friend void func(T u); // 僅 func 可存取 A,需前向宣告 func 模板
};
template
class MyClass {
friend void func(MyClass& arg) {
// 直接在類內實現
}
};
優點:簡潔,無連結問題。缺點:類定義膨脹,不適合複雜函式。
template
class MyClass {
template
friend void func(MyClass& arg); // 注意:新模板參數 C
};
template
void func(MyClass& arg) { ... } // 類外定義
優點:友元函式模板參數與類模板參數獨立,靈活度最高。
template
class A {
friend std::ostream& operator<< (std::ostream&, const A&); // 關鍵:
};
template
std::ostream& operator<<(std::ostream& os, const A& a) { ... }
優點:語意明確——友元正是對應類模板參數的那個函式模板實例。最符合直覺,推薦用於運算子重載。
<T>)。友元非成員函式,不參與模板實參推演。必須在宣告處明確告知編譯器「這是個模板」**,否則編譯器視為具體函式,導致實例化缺失、連結失敗。