首页 > 代码库 > C++模板 - value traits
C++模板 - value traits
前面的文章使用了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; }
C++模板 - value traits
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。