参数自动选择引用类型还是值类型

来源:互联网 发布:python量化投资 视频 编辑:程序博客网 时间:2024/05/16 09:42
 
对于泛型编程而言,不知道类型的大小,就不好判断选择传递参数时该选择值类型还是引用类型.对int,char这样的型别运用引用反到会使效率降低.下面是参考C++设计新思维的一个实现.
首先是一个型别选择器,根据flag标志判断是选择T,还是选择U,通过模板特化,当flag为true时选择T,当flag为false时选择U
 
   template<bool flag, typename T, typename U>
   class typeSelect
   {
   public:
        typedef T Result;
   };
 
   template<typename T, typename U>
   class typeSelect<false,T ,U>
   {
   public:
        typedef U Result;
   };
 
然后是一个把引用类型还原成原始类型的类,比如说把int&,还原成int.这样是为了防止出现引用的引用这种情况.它也是通过模板特化实现的.
     template<typename T>
     class referenceToOriginal
     {
     public:
         typedef T Type;
     };
 
     template<typename T>
     class referenceToOriginal<T&>
     {
     public:
         typedef T Type;
     };
 
 sizeCompare也是这里的一个辅助类,如果传入的类型的大小大于第二个模板参赛传入的类型,这MORE为true,否则为false.第二个模板参数默认为8,如果测试觉得不合适,可以更改.
不能直接比较
   template<typename T, int size = 8>
   class sizeCompare
   {
   public:
        enum{ MORE = sizeof(T) > size };
   };
  
   最后就是根据与传进的大小比较,选择类型
   template<typename T,int size = 8>
   class valOrRef
   {
        typedef typename referenceToOriginal<T>::Type U;
   public:
        typedef typename typeSelect<sizeCompare<U,size>::MORE,U&,U>::Result Type ;
   };
}
 
在使用的时候
template<typename T>
void Fun(typename valOrRef<T>::Type t)
{
}
 
template<typename T>
class Test
{
     typedef typename valOrRef<T>::Type type;
public:
      void output(type t)
      {
          cout<<t<<endl;
      }
};
 
int main()
{
     typedef valOrRef<int>::Type type;
     typedef valOrRef<string>::Type stype;
     //stype c; 会报错“c”: 必须初始化引用,说明这里选择的是引用类型
     type a = type();//不会报错,说明选择的是值类型
     string str("test");
 
    Test<int> tint;
     tint.output(a);
 
     Test<string> tstr;
     tstr.output(str);
 
     Fun<int>(a);
     Fun<string>(str);
}
这样模板类Test可以根据模板参数决定output的参数类型是值类型还是引用类型.
但也有一个缺陷,在使用模板函数的时候不能实现类型的自动推导
必须像
     Fun<int>(a);
     Fun<string>(str);
这样指明类型才可以调用,很不方便.
 
原创粉丝点击