STL 萃取(Traits)机制剖析
Posted windsun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL 萃取(Traits)机制剖析相关的知识,希望对你有一定的参考价值。
模板特化
在将萃取机制之前,先要说明模板特化
当有两个模板类,一个是通用泛型模板,一个是特殊类型模板,如果创建一个特殊类型的对象,会优先调用特殊的类型模板类,例如:
template <typename T> //泛型模板
class MyClass
public:
MyClass()
cout << "T MyClass!" << endl;
~MyClass()
cout << "~T MyClass!" << endl;
;
template<>
class MyClass<int> //全特化模板
public:
MyClass()
cout << "int MyClass!" << endl;
~MyClass()
cout << "~int MyClass!" << endl;
;
int main()
MyClass<char> mc0;
MyClass<int> mc1;
return 0;
运行结果:
T MyClass!
int MyClass!
~int MyClass!
~T MyClass!
萃取机制
现在举一系列例子来说明萃取机制
现在有两个类,需要完成相同的功能GetSum返回求和值
//int类型
class IntArray
public:
IntArray()
a = new int[10];
for (int i = 0; i < 10; ++i)
a[i] = i + 1;
~IntArray()
delete[] a;
int GetSum(int times) //对整数求和
int sum = 0;
for (int i = 0; i < 10; ++i)
sum += a[i];
cout << "int sum=" << sum << endl;
return sum * times;
private:
int *a;
;
//Float类型
class FloatArray
public:
FloatArray()
f = new float[10];
for (int i = 1; i <= 10; ++i)
f[i - 1] = 1.0f / i;
~FloatArray()
delete[] f;
float GetSum(float times) //对浮点数求和
float sum = 0.0f;
for (int i = 0; i < 10; i++)
sum += f[i];
cout << "float sum=" << sum << endl;
return sum * times;
private:
float* f;
;
我们可以看到,这样写代码冗余度很高,一部分功能比如GetSum函数,两个类都有,能不能用一个类完成?
先定义一个类,通过泛型,调用对应对象的GetSum函数得到结果。
template<class T>
class Apply
public:
float GetSum(T& t, float inarg)
return t.GetSum(inarg);
;
这种方法不能完全解决我们的问题(函数返回值和参数类型固定,就会导致异常),如何解决变化的输入输出参数?traits技术就能解决问题。
template<class T> //可以什么都不用写,说明定义了一个模板类
class NumTraits
;
//模板特化IntArray
template<>
class NumTraits<IntArray>
public:
typedef int resulttype;
typedef int inputargtype;
;
//模板特化FloatArray
template<>
class NumTraits<FloatArray>
public:
typedef float resulttype;
typedef float inputargtype;
;
template<class T>
class Apply2
public:
NumTraits<T>::resulttype GetSum(T& obj, NumTraits<T>::inputargtype inputarg)
return obj.GetSum(inputarg);
;
int main()
IntArray intary;
FloatArray floatary;
Apply2<IntArray> ai2; //采用萃取
Apply2<FloatArray> af2; //采用萃取
cout << "2整型数组的和3倍:" <<ai2.GetSum(intary,3) << endl; //返回整形
cout << "2浮点数组的和3.2倍:" << af2.GetSum(floatary,3.2f) << endl; //返回浮点型
return 0;
为什么两个类中都定义了resulttype和inputargtype,为什么要把返回类型、输入参数,都定义为相同的名称呢?因为为了编制模板类共同的调用接口做准备。
为了简化Apply2函数的定义形式,再次巧妙运用typedef进行定义,代码如下,与原始功能相同。
//泛型模板类
template<class T>
class NumTraits
; //可以什么都不用写,说明定义了一个模板类
template<> //模板特化
class NumTraits<IntArray>
public:
typedef int resulttype;
typedef int inputargtype;
;
template<> //模板特化
class NumTraits<FloatArray>
public:
typedef float resulttype;
typedef float inputargtype;
;
template<class T>
class Apply2
public:
typedef NumTraits<T>::resulttype result;
typedef NumTraits<T>::inputpara input;
result GetSum(T& obj, intput inputarg)
return obj.GetSum(inputarg);
;
总结
萃取机制在STL中被广泛运用,借助模板特化和和typedef可以将接口做到通用,降低了代码的冗余度,提高了代码的复用
?
以上是关于STL 萃取(Traits)机制剖析的主要内容,如果未能解决你的问题,请参考以下文章
还搞不懂STL的type_traits?从源码来带你一起分析!!!
还搞不懂STL的type_traits?从源码来带你一起分析