模板:policy类的简单使用

一、需求引入

到目前为止,我们一直都将累计(accumulation)与求和(summation)混为一谈。显然我们其实可以设想其它种类的累计。例如我们可以求给定之实值序列的乘积;如果被操作的实值是字串,我们可以将它们串接起来;甚至「寻找序列中的最大值」也可被归结为累计问题。在所有情况中,accum()惟一需要修改的就是  total  +=  *beg。这个操作可被称为「累计运算」过程中的一个  policy(策略)。因此所谓  policy   class  就是这样的  class:提供一个接口,从而得以在算法中运用一或多个  policies。 


二、实现

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; 

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

}; 
 
template<> 
class AccumulationTraits<float> { 
public: 
typedef double AccT; 
static AccT zero() { 
  return 0.0; 

}; 


//普通的求和代理类

class SumPolicy { 
public: 
template<typename T1, typename T2> 
static void accumulate (T1& total, T2 const & value) { 
total += value; 

};


//普通的求积代理类

class MultPolicy { 
public: 
template<typename T1, typename T2> 
static void accumulate (T1& total, T2 const& value) { 
total *= value; 
}  
};


//trait 和 policy的联合使用 模板

template <typename T, typename Policy = SumPolicy, 

typename Traits = AccumulationTraits<T> > 
class Accum { 
public: 

//定义trait的类型
typedef typename Traits::AccT AccT; 


//累积函数
static AccT accum (T const* beg, T const* end) { 

//初始化,注意使用MultPolicy 时,不能为 0

AccT total = Traits::zero();

 
while (beg != end) { 

//调用普通代理类的成员函数模板
Policy::accumulate(total, *beg);  
++beg; 

return total; 

}; 


三、使用

int main() { 


//  产生一个  array,内有  5  个整数值 
int num[] = { 1, 2, 3, 4, 5 }; 
 
//  打印所有数值的乘积 
std::cout << "the product of the integer values is " 
<< Accum<int,MultPolicy>::accum(&num[0], &num[5]) 
<< '\n'; 

 
然而上述程序的输出结果不如预期: 
 
the product of the integer values is 0 
 
问题在于我们对初始值的不当选择:初始值   0   对「求和」而言很合适,对「乘积」来说就不妥 了(初始值为  0,注定乘积结果也是  0)。这也说明了不同的  traits  和  policies  可能相互影响,同时也强调了谨慎设计  templates 的重要性。 
 
从这个例子中我们可以意识到,accumulation   loop(累计循环)的初始化应该成为   accumulation policy  的一个成份。这个  policy  可以使用也可以不使用  trait   zero()。其它替代方案也不该被遗忘   ―   并不是什么事都非得使用  traits  和  policies  解决不可。C++   标准库的accumulate()就是接受第三个  call argument 做为初始值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值