C++模板 - value traits

来源:互联网 发布:mac迅雷一直提示信任 编辑:程序博客网 时间:2024/05/17 09:01

前面的文章使用了type traits,其实traits还有value traits。

再看一下累加函数:

template<typename T>struct traits;template<>struct traits<char>{typedef int AccuT;};template<>struct traits<int>{typedef int AccuT;};template<class T>typename traits<T>::AccuT accum3(const T* ptr, int len){traits<T>::AccuT total = traits<T>::AccuT();for (int i = 0; i < len; i++){total += *(ptr + i);}return total;}

注意这行代码:

traits<T>::AccuT total = traits<T>::AccuT();

如果AccuT是int,float等类型,那么int(), float()就会初始化成0,没有问题,那么万一对应的类型不可以()初始化呢?

这个时候就用到了value traits,可以把int traits改成:

template<>struct traits<int>{typedef int AccuT;static AccuT const Zero = 0;};

这个traits里面有一个类型和一个值。

然后把累加函数改成:

template<class T>typename traits<T>::AccuT accum3(const T* ptr, int len){traits<T>::AccuT total = traits<T>::Zero;for (int i = 0; i < len; i++){total += *(ptr + i);}return total;}

 这样就可以解决初始化问题了。然后就算有变动也只需要修改traits里面的Zero了。

 

但是这么做也有个问题,就是并不是所有的类型都可以在类里面初始化,比如,我们把int traits的返回值类型改成double:

template<>struct traits<int>{typedef double AccuT;static AccuT const Zero = 0;};

这样编译器直接报错(vs2012),

error C2864: 'traits<int>::Zero' : only static const integral data members can be initialized within a class

有些人会在类外面来初始化这个值,比如:double const traits<int>::Zero = 0; 这也是个办法。但是感觉这不是个好办法。更一般的是在traits内部搞个静态函数,然后累加函数里面调用函数而不是静态变量。代码:

template<typename T>struct traits;template<>struct traits<char>{typedef int AccuT;static AccuT const Zero = 0;};template<>struct traits<int>{typedef double AccuT;static AccuT Zero(){ return 0.0; };};template<class T>typename traits<T>::AccuT accum3(const T* ptr, int len){traits<T>::AccuT total = traits<T>::Zero();for (int i = 0; i < len; i++){total += *(ptr + i);}return total;}int _tmain(int argc, _TCHAR* argv[]){int sz[] = {1, 2, 3};traits<int>::AccuT avg = accum3(sz, 3) / 3;return 0;}


 

 


 

 

 

 

 

 

0 0