参数自动选择引用类型还是值类型
2006-11-02 19:48
465 查看
对于泛型编程而言,不知道类型的大小,就不好判断选择传递参数时该选择值类型还是引用类型.对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);
这样指明类型才可以调用,很不方便.
首先是一个型别选择器,根据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);
这样指明类型才可以调用,很不方便.
相关文章推荐
- 引用类型传递参数到底传的是值还是引用
- WCF客户端引用带有 int bool 类型的方法时,会自动加上一个Specified参数的 解决方法 Web Reference for a WCF Service has Extra “IdSpecified” Parameter -摘自网络
- Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?
- C#(也适用其他)的初学者对string是值类型还是引用类型搞不清楚,还有对参数传递也比较迷糊
- 面试之路(18)-java的函数参数传递类型之值传递还是引用传递
- 面试之路(18)-java的函数参数传递类型之值传递还是引用传递
- 面试之路(18)-java的函数参数传递类型之值传递还是引用传递
- 面试之路(18)-java的函数参数传递类型之值传递还是引用传递
- [对象和类型]5.引用传参和值传参:ref参数,out参数
- 修改时,select根据参数自动选择其中某项
- 慎用 const 引用参数类型
- Java中的对象类型像引用还是指针,谁是谁非?
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 重载操作符时不管类成员还是名字空间成员,对于参数都支持类型转换
- ios学习之 方法中的参数为引用类型
- 拷贝构造函数的参数为什么必须使用引用类型
- java的方法调用,参数是按值传递还是按引用传递
- 由【JAVA中参数传递问题】引发除了基本数据类型和引用类型的思考
- JavaScript 函数参数传递到底是值传递还是引用传递
- Java方法参数是引用调用还是值调用?——值调用