trait编程技法

traits技法简单入门

首先要对元编程有所了解,要知道模板类,如果用过STL就更好了。

我最早是在STL源码剖析一书中看到trait技法的,运用这一技法将本来在runtime时完成的工作转到了编译时期完成。

下面是一个通常用来作示例的,关于元编程的例子,读者自己去体会。

struct fibonacci

{

       enum{value=fibonacci<n-1>::value+fibonacci<n-2>::value};

};

template<>

struct fibonacci<1>

{

       enum{value=1};

};

template<>

struct fibonacci<0>

{

       enum{value=0};

};

 

 下面讲一个trait的应用示例。【1】

template<typename T>

void doSomething(T& t)

{

     if(t 具有某种特性)

    {

      做一些事情

    }

    else

    {

      做另一些事情

    }

}

对上面这段代码改进到编译期完成: 

首先,定义表示‘真’和‘假’的类:

struct _true_type{};

struct _false_type{};

它们对应于运行期的值,true和false;

再将特性定义成内嵌类型的typedef:

class T

{

   typedef _true_type copiable;

};

然后在doSomething()里做类型推导:

template<typename T>

void doSomething(T& t)

{

  typedef typename T::copiable copiable;

  doSomething_aux(t,copiable());

}

真正在推导的是另一个重载的函数doSomething_aux,如下定义

template<typename T>

void doSomething_aux(T& t,_true_type)

{

  当可以拷贝时做的事情

}

template<typename T>

void doSomething_aux(T& t,_false_type)

{

 当不可以拷贝时做的事情

}

这样就大功告成,似乎只用到了重载函数,但是这样的特性方法不能推广到基本类型,比如,T是int型,那在doSomething里就出错了,int::copiable没有定义,当然啦,你不可能把这个特性加进去。

再加一层封装可以解决这个问题:

template<typename T>

struct type_traits

{

  typedef T::copiable copiable;

};

然后改写doSomething:

template<typename T>

void doSomething(T& t)

{

  typedef typename type_traits<T>::copiable copiable;

  doSomething_aux(t,copiable());

}

为什么要转这么个弯?因为这样做了就有机会为基本类型添加特性信息,我们可以特化这个type_traits为基本类型,如

template<>

struct type_traits<int>

{

  typedef _true_type copiable;

};

STL里有个文件type_traits.h里面就定义了所有这些基本类型的偏特化版,当然,这里的copiable是我想出来的一个特性。

不仅仅只能为type可以定义traits,还可以为其它很多概念定义traits,比如iterator,它的偏特化版就牵扯到原始指针,可以认为,原始指针是一种iterator,而iterator是一个抽象的概念。

大致是这样的了。

参考资料:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值