模板類的約束模板友元函數:template friend functions


本來這篇博客是不打算寫的,內容不是很難,對於我自己來講,更多的是為了突出細節。

  • 所謂template friend functions,就是使友元函數本身成為模板。基本步驟:
    1,在類定義的前面聲明每個模板函數。eg:template <typename T> void counts(); template <typename T> void report<>(T &);
    2,在類聲明中再次將模板聲明為友元。
    template <typename TT>
    class HasFriendT
    {
        ....
        friend void counts<TT>();
        friend void report<>(Testclass<TT> &)   
    };

    聲明中<>指出這是模板具體化,注意模板具體化和函數具體化有點不一樣。對於report,<>可以為空,因為可以從函數參數推斷出模板類型參數。在聲明的例子中是:HasfriendT<TT>。然而,也可以使用report<HasFriendT<TT>> 來代替 report<>
    但是counts沒有參數,因此必須使用模板參數語法(<TT>)來指明其具體化。還要注意的是,TT是Testclass類的參數類型
    3,為友元提供模板定義。這里的定義只是就“泛型”TT,每個函數定義一個就行。並不需要像函數顯式具體化那樣為每個特定的類型通通都定義。

  • 好了,接下來看代碼:
     1  #include <iostream>
     2  
     3  using std::cout;
     4  using std::endl;
     5  
     6  template <typename T> void counts();
     7  template <typename T> void report(T &); 
     8  
     9  template <typename TT> 
    10  class HasFriendT
    11  {
    12      private:
    13          TT item;
    14          static int ct; 
    15      public:
    16          HasFriendT(const TT & i) : item(i) { ct++; }
    17          ~HasFriendT() { ct--; }
    18          friend void counts<TT>();
    19          friend void report<HasFriendT<TT>>(HasFriendT<TT> &); 
    20          //note: use report<HasFriendT<TT>> not report<TT>
    21  };
    22  
    23  template <typename T>
    24  int HasFriendT<T>::ct = 0;
    25  
    26  template <typename T>
    27  void counts()
    28  {
    29      cout << "template size: " << sizeof(HasFriendT<T>) << "; ";
    30      cout << "template counts(): " << HasFriendT<T>::ct << endl;
    31  }
    32  
    33 template <typename T>
    34  void report(T & hf)
    35  {
    36      cout << hf.item << endl;
    37  }
    38  
    39  int main(void)
    40  {
    41      counts<int>();
    42      HasFriendT<int> hfi1(11);
    43      HasFriendT<int> hfi2(22);
    44      HasFriendT<double> hfi3(15.5);
    45  
    46      report(hfi1);
    47      report(hfi2);
    48      report(hfi3);
    49  
    50      cout << "counts<int>() output: \n";
    51      counts<int>();
    52      cout << "counts<double>() output: \n";
    53      counts<double>();
    54  
    55      return 0;
    56  }

     開始的時侯,在聲明模板時明明counts 和 report 的<>內都是typename T(即<typename T>),我想不明白為什么在class中friend void counts<TT>() 和 friend void report<HasFriendT<TT>>(HasFriendT<TT> &) <>內的參數就不一樣了呢(一個是<HasfriendT<TT>> 一個 是 <TT>)。后來仔細看了下,才發現report函數和counts函數處理的對象不一樣。report處理的是item,它是類HasFrriendT的成員數據,所以它的類型是<HasFriendT<TT>>。而counts處理的是一個靜態成員,對於靜態類成員,可以在類聲明之外使用單獨的語句進行初始化,這是因為靜態類是單獨存儲的,而不是對象的組成部分。也正如本文開頭所指出那樣:在countsde<>中, TT是Testclass類的參數類型。 

  • 不知到你有沒有發現上面的聲明中,一會用TT,一會用T。開始我也納悶,神經兮兮的認為它們的不同是不是隱含什么細節。后來將它們全部改成TT再編譯,發現沒什么問題。原來這只是一個泛型的符號而已。。當然,它們也可能真的存在什么不同,但現在我還沒有發現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM