策略类模板
在前面的博文中,策略类SumPolicy
和MinPolicy
都是普通的类,其中包含的是一个静态成员函数模板algorithm()
,该函数模板包含两个类型模板参数。其实,也可以把SumPolicy
和MinPolicy类
写成类模板—直接把algorithm()
中的两个类型模板参数搬到类定义上面作为类模板的模板参数就可以了。类模板SumPolicy
和MinPolicy
的实现代码如下。
template<typename sumT,typename T>
struct SumPolicy
{
static void algorithm(sumT& sum, const T& value)
{
sum += value;
}
};
template<typename minT,typename T>
struct MinPolicy
{
static void algorithm(minT& min, const T& value)
{
if (min > value)
min = value;
}
};
当然,同样要修改funcsum()
函数模板,该函数模板的第3个类型模板参数要作出改变,当前第3个类型模板参数的默认值是SumPolicy
,这是一个类型,但是,修改后的SumPolicy
已经是一个类模板了,所以funcsum()
函数模板的第3个模板参数必须是一个模板模板参数。修改后的funcsum()
函数模板如下。
// 这里的class也可以写成typename
template<typename T,typename U = SumFixedTraits<T>,template<class,class> class V = SumPolicy>
auto funcsum(const T* begin, const T* end)
{
typename U::sumT sum = U::initValue();
for (;;)
{
V<U::sumT, T>::algorithm(sum, *begin);
// T时数组成员类型,U是固定萃取类模板,从中可以提取出计算的结果类型(U::sumT)
// 以及结果的初值,V是策略类模板,用于实现具体算法(求和,求最小值等)
if (begin == end)
break;
++begin;
}
return sum;
}
完整且完美的代码,如下:
#include "killCmake.h"
#include<string>
using namespace std;
template<typename T>
struct SumFixedTraits;
template<>
struct SumFixedTraits<char>
{
using sumT = int;
static sumT initValue() {
return 0;
}
};
template<>
struct SumFixedTraits<double>
{
using sumT = double;
static sumT initValue() {
return 0.0;
}
};
template<typename T>
struct MinFixedTraits;
template<>
struct MinFixedTraits<int>
{
// 求最小值,结果类型与元素类型相同即可
// 为名字统一,都用sumT这个名字
using sumT = int;
static sumT initValue()
{
// 这里给整型最大值,相信任何一个数组元素都不会比这个值更大
// 因此可以顺利找到数组元素中的最小值
return INT_MAX;
}
};
template<typename sumT,typename T>
struct SumPolicy
{
static void algorithm(sumT& sum, const T& value)
{
sum += value;
}
};
template<typename minT,typename T>
struct MinPolicy
{
static void algorithm(minT& min, const T& value)
{
if (min > value)
min = value;
}
};
// 这里的class也可以写成typename
template<typename T,typename U = SumFixedTraits<T>,template<class,class> class V = SumPolicy>
auto funcsum(const T* begin, const T* end)
{
typename U::sumT sum = U::initValue();
for (;;)
{
V<typename U::sumT, T>::algorithm(sum, *begin);
// T时数组成员类型,U是固定萃取类模板,从中可以提取出计算的结果类型(U::sumT)
// 以及结果的初值,V是策略类模板,用于实现具体算法(求和,求最小值等)
if (begin == end)
break;
++begin;
}
return sum;
}
int main()
{
int my_int_array1[] = { 10,15,20 };
std::cout << funcsum<int, MinFixedTraits<int>, MinPolicy>(& my_int_array1[0], & my_int_array1[2]) << std::endl;
return 0;
}
萃取技术与策略技术的比较
- 之前的博文,学习了
萃取(trait)技术
,也学习了策略(policy)技术
,对于萃取技术,通过范例展示了固定萃取和值萃取;对于策略技术,展示了算法策略。萃取技术和策略技术很相似,注意它们之间的相同与不同之处。
- (1)两种技术都像一个中间件一样,夹在不同的功能代码之间,使代码之间的调用(交互)更加灵活。
- (2)萃取技术传入一个类型,萃取出另外一个类型或值(注重类型或值);而策略技术是传入一个类型,萃取出一个算法,或者说是一个不同的功能实现(注重动作或行为)。因此,书写策略类(类模板)时通常都需要包含成员函数以实现指定的行为。但在实际的项目实现中,也可能会在萃取类中实现某些动作或行为,从这个角度来讲,两种技术有时区分并不是那么明显。
- (3)萃取技术一般通过一个类模板来实现,通常包含类模板的泛化版本和多个特化版本。而策略技术用普通类或类模板都可以实现。