1. 程式人生 > >C++模板類內友元(友元函式,友元類)宣告的三種情況

C++模板類內友元(友元函式,友元類)宣告的三種情況

根據《C++ Primer》第三版16.4節的敘述,C++類模板友元分為以下幾種情況
1.非模板友元類或友元函式。 書上給了一個例子:
class Foo{
    void bar();
};
template <class T>
class QueueItem{
    friend class foobar;
    friend void foo();
    friend void Foo::bar();
    //....
};
很簡單,跟非模板類沒什麼區別,有一點需要注意,如果要把函式和類生命為友元,前面不需要宣告或定義。但是如果要把類成員函式宣告為友元,則前面必須有類的定義(注意不是宣告,是定義),因為
一個類成員只能由該類的定義引入 。

2.繫結的友元類模板或函式模板。 例子如下:
template <class Type>
    class foobar{ ...};

template <class Type>
    void foo(QueueItem<Type>);

template <class Type>
class Queue{
    void bar();
    //...
};

template <class Type>
class QueueItem {
    friend class foobar<Type> ;
    friend void foo
<Type> (QueueItem<Type>);
    friend void Queue<Type> ::bar();
    //...
};
需要注意兩點:
    a.與非模板函式或類不同,模板函式或類宣告為友元之前必須在前面宣告過 ,否則無法通過編譯。
    b.注意紅字部分,那幾個Type不能少。比如對於函式foo,如果少了<Type>的話編譯器會將其作為非模板函式對待,也就是說,對於QueueItem<int>,編譯器會查詢void foo(QueueItem<int>),而對template<class T>void foo(QueueItem<T>)視而不見,如果沒找到非模板函式則會報錯。


3.非繫結友元類模板或函式模板。 舉例如下:
template <class Type>
class QueueItem {
    template<class T>
        friend class foobar;

    template<class T>
        friend void foo(QueueItem<T>);

    template<class T>
        friend void Queue<T>::bar();
    //...

};