网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > C/C++ > 正文
C++模板元编程
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/15
下载{$ArticleTitle}原创论文样式

模板元编程技术最早的实际应用之一是用于数值计算中的解循环。举个例子,对一个数组进行求和的常见方法是:

// sumarray.h

template <typename T>
inline T sum_array(int Dim, T* a)
{
T result = T();
for (int i = 0; i < Dim; ++i)
{
result += a[i];
}
return result;
}

这当然可行,但我们也可以利用模板元编程技术来解开循环:

// sumarray2.h

// 原始模板
template <int Dim, typename T>
class Sumarray
{
public:
static T result(T* a)
{
return a[0] + Sumarray<Dim-1, T>::result(a+1);
}
};

// 作为终结准则的局部特化版
template <typename T>
class Sumarray<1, T>
{
public:
static T result(T* a)
{
return a[0];
}
};

用法如下:

// sumarraytest2.cpp

#include <iostream>
#include "sumarray2.h"

int main()
{
int a = {1, 2, 3, 4, 5, 6};
std::cout << " Sumarray<6>(a) = " << Sumarray<6, int>::result(a);
}

当我们计算Sumarray<6, int>::result(a)时,实例化过程如下:

Sumarray<6, int>::result(a)
= a[0] + Sumvector<5, int>::result(a+1)
= a[0] + a + Sumvector<4, int>::result(a+2)
= a[0] + a + a + Sumvector<3, int>::result(a+3)
= a[0] + a + a + a + Sumvector<2, int>::result(a+4)
= a[0] + a + a + a + a + Sumvector<1, int>::result(a+5)
= a[0] + a + a + a + a + a

可见,循环被展开为a[0] + a + a + a + a + a。这种直截了当的展开运算几乎总是比循环来得更有效率。

也许拿一个有着600万个元素的数组来例证循环开解的优势可能更有说服力。生成这样的数组很容易,有兴趣,你不妨测试、对比一下。

(感谢一位朋友的测试。他说 ,“据在Visual C++ 2003上实测编译器应当进行了尾递归优化,可以不受上面说的递归层次的限制,然而连加的结果在数组个数达到4796之后就不再正确了,程序输出了空行,已经出错” — 2003年12月30日补充)

模板元编程在数值计算程序库中的应用

Blitz++之所以“快如闪电”(这正是blitz的字面含义),离不开模板元程序的功劳。Blitz++淋漓尽致地使用了元编程技术,你可以到这些文件源代码中窥探究竟:

dot.h

matassign.h

matmat.h

matvec.h

metaprog.h

product.h

sum.h

vecassign.h

让我们看看Blitz++程序库dot.h文件中的模板元程序

template<int N, int I>
class _bz_meta_vectorDot {
public:
enum { loopFlag = (I < N-1) ? 1 : 0 };

template<class T_expr1, class T_expr2>
static inline BZ_PROMOTE(_bz_typename T_expr1::T_numtype, _bz_typename T_expr2::T_numtype)
f(const 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_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

  • 上一篇资讯: C++多态技术
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号