Policy用来制定算法采取的策略,使用Policy可以是的算法的策略可以修改,控制粒度更加的小。
#ifndef TRAIT_H_
#define TRAIT_H_
/*
template<typename T>
T accumulate( const T *begin, const T *end )
{
T total = T();
while ( begin != end ) {
total += *begin;
++begin;
}
return total;
}*/
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 long AccT;
static AccT zero() {
return 0;
}
};
template<>
class AccumulationTraits<unsigned int>
{
public:
typedef unsigned long long AccT;
static AccT zero() {
return 0;
}
};
template<>
class AccumulationTraits<float>
{
public:
typedef double AccT;
static AccT zero() {
return 0;
}
};
class SumPolicy {
public:
template<typename T1, typename T2>
static void accumulate(T1 &total, const T2 &value) {
total += value;
}
};
class MultiPolicy {
public:
template<typename T1, typename T2>
static void accumulate(T1 &total, const T2 &value) {
total *= value;
}
};
template<typename T, typename Policy = SumPolicy, typename AT = AccumulationTraits<T> >
class Accum
{
public:
static typename AT::AccT accumulate( const T *begin, const T *end ) {
typename AT::AccT total = AT::zero();
while ( begin != end ) {
Policy::accumulate(total, *begin);
++begin;
}
return total;
}
};
template<typename T>
typename AccumulationTraits<T>::AccT accumulate( const T *begin,
const T *end )
{
return Accum<T>::accumulate( begin, end );
}
template<typename Traits, typename T>
typename Traits::AccT accumulate( const T *begin, const T *end )
{
return Accum<T, SumPolicy, Traits>::accumulate( begin, end );
}
template<typename Policy, typename Traits, typename T>
typename Traits::AccT accumulate( const T *begin, const T *end )
{
return Accum<T, Policy, Traits>::accumulate(begin, end);
}
#endif
int iv[5] = {1, 2, 3, 4, 5};
double ftotal = accumulate<MultiPolicy, typename AccumulationTraits<float>, int>( iv, iv + sizeof( iv ) / sizeof( int ) );
EXPECT_EQ( 0, ftotal );
char cv[] = {'a', 'a', 'b', 'b'};
int total = 97 * 2 + 98 * 2;
EXPECT_EQ( total , accumulate( cv, cv + sizeof( cv ) / sizeof( char ) ) );