trait和policy类

trait

先看下面代码:

//accumtraits.h
template <typename T>
class AccumulationTraits;

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

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

//accum.h
#include "accumtraits.h"
template <typename T>
inline typename AccumulationTraits::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;
}

上面代码中,accum是一个求和的函数模板,而关键点在于total这个变量的类型和zero的值,这些是和模板参数T相关的:例如当模板实参为int,那total类型应该取long;当模板实参为char,total类型应该取int。
trait有特征的意思,把所有的T相关特征封装起来(这里特征更多指的是属性),就成了trait类模板AcculationTraits<>。

policy

trait是把T相关属性封装起来的一种技巧,也可以把T相关行为封装起来,称作policy:

// accum.h
template <typename T, typename Policy = SumPolicy, typename Traits = AccumulationTraits<T> >
class Accum
{
public:
	typedef typename Traits::Acct Acct;
	static Acct accum(T const *beg, T const *end)
	{
		Acct total = Traits::zero();
		while (beg != end)
		{
			Policy::accumulate(total, *beg);
			++beg;
		}
		return total;
	}
};

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

上面代码把SumPolicy实现为普通类,而把accumulate实现为成员函数模板,当然也可以反过来。

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

// accum.h
template <typename T,
		  template<typename, typename> class Policy = SumPolicy,
		  typename Traits = AccumulationTraits<T> >
class Accum
{
public:
	typedef typename Traits::Acct Acct;
	static Acct accum(T const *beg, T const *end)
	{
		Acct total = Traits::zero();
		while (beg != end)
		{
			Policy<Acct, T>::accumulate(total, *beg);
			++beg;
		}
		return total;
	}	
};

trait的应用——提取类型

一些情况下,模板参数之前是存在依赖关系的,换句话说,在编译期部分参数可以根据其它参数来确定。

如果我们想实现一个模板函数,计算容器中所有元素的和,那么可以这样定义:

template <typename T, typename C>
T sum_of_elements(C const& c)
{
}

显然,返回类型T是根据容器元素类型来决定的,标准容器都定义有value_type这个成员变量。于是,可以把返回类型这一特征提取出来,放在一个命名为ElementT的trait模板中:

template <typename C>
class ElementT
{
publictypedef typename C::value_type Type;
};

// 可以利用特化进行一些特殊处理
template <typename>
class ElementT<vector<string> >
{
public:
	typedef int Type;
}

template <typename C>
typename ElementT<C>::Type sum_of_elements(C const& c)
{
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值