C++模板元编程


    template<class T_expr1, class T_expr2>
    static inline BZ_PROMOTE(_bz_typename T_expr1::T_numtype, _bz_typename T_expr2::T_numtype)
    f_value_ref(T_expr1 a, const T_expr2& b)
    {
        return a[I] * b[I] + _bz_meta_vectorDot<loopFlag * N, loopFlag * (I+1)>::f(a,b);
    }

    template<class T_expr1, class T_expr2>
    static inline BZ_PROMOTE(_bz_typename T_expr1::T_numtype, _bz_typename T_expr2::T_numtype)
    f_ref_value(const T_expr1& a, T_expr2 b)
    {
        return a[I] * b[I] + _bz_meta_vectorDot<loopFlag * N, loopFlag * (I+1)>::f(a,b);
    }

    template<class T_expr1, class P_numtype2>
    static inline BZ_PROMOTE(_bz_typename T_expr1::T_numtype, P_numtype2)
    dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0,
                P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0,
                P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0)
    {
        return a[I] * i1 + _bz_meta_vectorDot<loopFlag * N, loopFlag * (I+1)>::dotWithArgs
                                                                                   (a, i2, i3, i4, i5, i6, i7, i8, i9);
    }
};

template<>
class _bz_meta_vectorDot<0,0> {
public:
    template<class T_expr1, class T_expr2>
    static inline _bz_meta_nullOperand f(const T_expr1&, const T_expr2&)
    { return _bz_meta_nullOperand(); }

    template<class T_expr1, class P_numtype2>
    static inline _bz_meta_nullOperand 
    dotWithArgs(const T_expr1& a, P_numtype2 i1, P_numtype2 i2=0,
                P_numtype2 i3=0, P_numtype2 i4=0, P_numtype2 i5=0, P_numtype2 i6=0,
                P_numtype2 i7=0, P_numtype2 i8=0, P_numtype2 i9=0, P_numtype2 i10=0)
    {
        return _bz_meta_nullOperand(); 
    }
};
这段代码远比它乍看上去的简单。_bz_meta_vectorDot类模板使用了一个临时变量loopFlag来存放每一步循环条件的评估结果,并使用了一个完全特化版作为递归终结的条件。需要说明的是,和几乎所有元程序一样,这个临时变量作用发挥于编译期,并将从运行代码中优化掉。 
Todd是在Blitz++数值数组库的主要作者。这个程序库(以及MTL和POOMA等程序库)例证了模板元程序可以为我们带来更加高效的数值计算性能。Todd宣称Blitz++的性能可以和对应的Fortran程序库媲美。
 
Loki程序库:活用模板元编程技术的典范 

模板元编程的价值仅仅在于高性能数值计算吗?不仅如此。Loki程序库以对泛型模式的开创性工作闻名于C++社群。它很巧妙地利用了模板元编程技术实现了Typelist组件。Typelist是实现Abstract Factory、Visitor等泛型模式不可或缺的基础设施。 
就像C++标准库组件std::list提供对一组数值的操作一样,Typelist可以用来操纵一组类型,其定义非常简单(摘自Loki程序库Typelist.h单元): 
template <class T, class U>
struct Typelist
{
    typedef T Head;
    typedef U Tail;
}; 
显然,Typelist没有任何状态,也未定义任何操作,其作用只在于携带类型信息,它并未打算被实例化,因此,对于Typelist的任何处理都必然发生于编译期而非运行期。 
Typelist可以被无限扩展,因为模板参数可以是任何类型(包括该模板的其他具现体)。例如: 
Typelist<char, Typelist<int, Typelist<float, NullType> > >  
就是一个包含有char、int、float三种类型的Typelist。 
按照Loki的约定,每一个Typelist都必须以NullType结尾。NullType的作用类似于传统C字符串的“\0”,它被声明于Loki程序库的NullType.h文件中: 
class NullType; 
NullType只有声明,没有定义,因为Loki程序库永远都不需要创建一个NullType对象。 
让我们看看IndexOf模板元程序,它可以在一个Typelist中查找给定类型的位置(摘自Loki程序库的Typelist.h单元): 
template <class TList, class T>
struct IndexOf;

template <class T>
struct IndexOf<NullType, T>
{
    enum { value = -1 };
};

template <class T, class Tail>
struct IndexOf<Typelist<T, Tail>, T>
{
    enum { value = 0 };
};

template <class Head, class Tail, class T>
struct IndexOf<Typelist<Head, Tail>, T>
{
private:
共5页 首页 上一页 [1] [2] [3] [4] [5下一页 尾页>
相关信息
相关评论
相关文章
字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z