zoukankan      html  css  js  c++  java
  • 模板类的约束模板友元函数: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: 
      ";
      51      counts<int>();
      52      cout << "counts<double>() output: 
      ";
      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再编译,发现没什么问题。原来这只是一个泛型的符号而已。。当然,它们也可能真的存在什么不同,但现在我还没有发现。
  • 相关阅读:
    C#基础笔记(第十四天)
    C#基础笔记(第十三天)
    C#基础整理(二)
    C#基础笔记(第十二天)
    C#基础笔记(第十一天)
    C#基础笔记(第十天)
    C#基础笔记(第九天)
    [PyTorch 学习笔记] 2.3 二十二种 transforms 图片数据预处理方法
    [PyTorch 学习笔记] 2.2 图片预处理 transforms 模块机制
    [PyTorch 学习笔记] 2.1 DataLoader 与 DataSet
  • 原文地址:https://www.cnblogs.com/busui/p/5797179.html
Copyright © 2011-2022 走看看