现在的位置: 首页 > 综合 > 正文

模板的使用

2013年12月02日 ⁄ 综合 ⁄ 共 1534字 ⁄ 字号 评论关闭

看了很多模板的书一直没有实践, 最近把原来的基类的代码用模板改了下

template<typename T> class Rect{
    friend class RectCmp<T>;
public:
       Rect();
       ...

private:
union{
    struct{    
        T x1;
        T y1;
        T x2;
        T y2;
   };
   T elems[4];
};
};


template<typename T>Rect<T>::Rect(){ ... }

基本方法如此,很简单, 但是使用模板遇到一个很麻烦的问题,就是和接口的封装冲突比较大,因为他要求把实现和定义都写在同一个文件里面,这也是为什么模板函数都要inline的原因,(export 关键字有一些负作用,前途未卜),这样对接口的封装影响比较大。

下面介绍一下模板的trait 和 policy 类

trait 就是对另一种类型的封装, 比如用trait来解决一个加法溢出的问题

// 用int来封装char,避免溢出
template<>
class AccumulationTraits<char>{
public:
     typdef int AccT;
     static AccT const zero() { return 0 };   // 定义 zero, static可以节省内存
};


// 做加法运算
template<typename T> inline typename AccumulationTraits<T>::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;
}

policy,就是采用的一种把算法当成对象的方法,所以有很多基于policy的design pattern的实现。

比如上面的例子,我们现在不仅要做加法还要做乘法运算。

// 加法
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; }
};


// policy的调用
template<typename T, typename Policy, typename Traits>
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;   
    }
};

// 使用:total = Accum<char, MultPolicy, AccumulationTraits<char> >::accum(&num[0], &num[5]);

小技巧:

模板借助sizeof 可以用来显示数组的长度

template <typename T, int N>class A{
    T a[N];
};


sizeof(A<float, 100>);

小问题:

template 到 template 的 typedef 不支持,不小的C++11对此怎么说。

... to be continued...

抱歉!评论已关闭.