现在的位置: 首页 > 综合 > 正文

C++模板元编程——Traits

2017年12月07日 ⁄ 综合 ⁄ 共 2813字 ⁄ 字号 评论关闭

[转]C++模板元编程——Traits

通过一个计算序列元素的累加和的小函数来说明traits的使用。
计算一个序列的累加和:

template<typename T>
T accum(const T* beg, const T* end)
{
T total = T();
while(beg != end)
{
total += *beg;
++beg;
}
return total;
}
使用accum:
  int a[] = {3, 5, 7, 9};
const char* str = "abcd";
cout << "the a average: " <<  accum(a,a + 4) / 4 << endl; 
cout << "the str average: " << accum(str,str + 4) / 4 << endl;
输出结果:
the a average: 6
the str average: -29

问题来了,"abcd" 串的平均值居然是-29, 这明显是不对的。问题出在T  total,total 的类型为char,导致total += *beg 溢出。

解决的办法是通过类型T,得到一个比T能够表达更大范围的类型T1, 尽可能的保证不溢出。

1 特征类(traits)

定义AccumTraits特征类:

template<typename T>

struct AccumTraits

{

typedef T type; //默认情况下AccumTraits<T>::type 即为T

};

AccumTraits特征类char类型的特化:

template<>

struct AccumTraits<char>

{

typedef int type; //  //AccumTraits<char>::type 即为int

};

AccumTraits特征类int类型的特化:

template<>

struct AccumTraits<int>

{

typedef long type;

};

应该特化各种常用的容易溢出的类型如:char、short、int、float,以及相应的unsigned char、unsigned short ...

重新实现accum模板函数:

template<typename T> 
typename AccumTraits<T>::type 
accum(const T* beg, const T* end) 
{ 
typename AccumTraits<T>::type total  = AccumTraits<T>::type(); 
while(beg != end) 
{ 
total += *beg; 
++beg; 
} 
return total; 
} 
再次使用该函数: 
  int a[] = {3, 5, 7, 9}; 
const char* str = "abcd"; 
cout << "the a average: " <<  accum(a,a + 4) / 4 << endl; 
cout << "the str average: " << accum(str,str + 4) / 4 << endl; 
输出结果: 
the a average: 6 
the str average: 98

抱歉!评论已关闭.