一个简单的Traits进阶过程

设计一个模板函数,用来求和。并且用Traits机制一步一步完善:

//traits/accum1.h
#ifndef ACCUM_H
#define ACCUM_H
template <typename T>
inline
T accum(T const* beg, T const* end)
{
 T total = T();
 while(beg != end){
  total +=*beg;
  ++beg;
 }
 return total;
}
#endif //ACCUM_H

#include "stdafx.h"
#include "accum1.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
 int num[] = {1,2,3,4,5};
 cout<<"the average value of the integer values is "
  <<accum(&num[0], &num[5])/5<<endl;
 char name[] = "templates";
 int length = sizeof(name)-1;
 cout<<"the average value of the characters in /""
  << name<<"/" is "
  <<accum(&name[0],&name[length])/length<<endl;
 return 0;
}

 仔细分析以上代码,会发现一个问题,首先 对于Char 而言,main函数会输出错误的结果,因为char的位数有限,所以导致求出的平均值有误(数组之和大于255,导致平均值为-5),其次 T total = T();并不能满足任意类型。

于是我们利用Traits机制邦定T的特征。

//accumtraits2.h

template<typename T>
class AccumulationTraits;

template<>
class AccumulationTraits<char>{
public:
 typedef int AccT;
 static AccT const zero = 0;
};

template<>
class AccumulationTraits<short>{
public:
 typedef int AccT;
 static AccT const zero = 0;
};

template<>
class AccumulationTraits<int>{
public:
 typedef long AccT;
 static AccT const zero = 0;
};

//accum2.h

#ifndef ACCUM_H
#define ACCUM_H

#include "accumtraits2.h"

template<typename T>
inline
typename AccumulationTraits<T>::AccT accum(T const* beg, T const* end)
{
 typedef typename AccumulationTraits<T>::AccT AccT;

 AccT total = AccumulationTraits<T>::zero;
 while(beg != end){
  total +=*beg;
  ++beg;
 }
 return total;
}
#endif //ACCUM_H

以上代码可以解决上述提到的两个问题。但是针对

template<>
class AccumulationTraits<float>{
public:
 typedef double AccT;
 static AccT const zero = 0.0;//错误,C++只允许我们对整型和枚举类型初始化成静态成员变量。
};

可重新实现如下

template<>
class AccumulationTraits<float>{
public:
 typedef double AccT;
 static AccT const zero;//这里只有声明};

将初始化写在源文件中

double const AccmulatinTraits<float>::zero = 0.0;

但新的问题又来了:这种解决方案对编译器而言是不可知的。

于是我们又得到了下面新的解决方案:

//accumtraits3.h

template<typename T>
class AccumulationTraits;

template<>
class AccumulationTraits<char>{
public:
 typedef int AccT;
 static AccT zero(){
  return 0;
 }

};

template<>
class AccumulationTraits<short>{
public:
 typedef int AccT;
 static AccT zero(){
  return 0;
 }

};

template<>
class AccumulationTraits<int>{
public:
 typedef long AccT;
 static AccT zero(){
  return 0;
 }

};

//accum3.h

#include "accumtraits3.h"

template<typename T>
inline
typename AccumulationTraits<T>::AccT accum(T const* beg, T const* end)
{
 typedef typename AccumulationTraits<T>::AccT AccT;

 AccT total = AccumulationTraits<T>::zero();
 while(beg != end){
  total +=*beg;
  ++beg;
 }
 return total;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值