首页产品库评测行情新闻|手机数码笔记本台式机DIY硬件数字家庭数码相机办公外设|软件下载游戏开发|社区

更多

数码相机
MP4
LCD
机箱
音箱

天极网 > 开发频道>C++模板元编程技术研究

C++模板元编程技术研究

2004-01-06 17:14作者:ADJS出处:论坛责任编辑:方舟

天极IT资讯短信服务 电脑小技巧
资费:包月5元
手机:
介绍:细处着手,巧处用功。高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些。电脑小技巧收集最新奇招高招,让你轻松踏上高手之路。


  摘要

  本文描述了模板元编程技术的起源、概念和机制,并介绍了模板元编程技术在Blitz++和Loki程序库中的应用。

  关键字

  编译期计算 模板元编程 Blitz++ Loki

  导言

  1994年,C++标准委员会在圣迭哥举行的一次会议期间Erwin Unruh展示了一段可以产生质数的代码。这段代码的特别之处在于质数产生于编译期而非运行期,在编译器产生的一系列错误信息中间夹杂着从2到某个设定值之间的所有质数:

// Prime number computation by Erwin Unruh
template <int i> struct D { D(void*); operator int(); };

template <int p, int i> struct is_prime {
enum { prim = (p%i) && is_prime<(i > 2 ? p : 0), i -1> :: prim };
};

template < int i > struct Prime_print {
Prime_print<i-1> a;
enum { prim = is_prime<i, i-1>::prim };
void f() { D<i> d = prim; }
};

struct is_prime<0,0> { enum {prim=1}; };
struct is_prime<0,1> { enum {prim=1}; };
struct Prime_print<2> { enum {prim = 1}; void f() { D<2> d = prim; } };
#ifndef LAST
#define LAST 10
#endif
main () {
Prime_print<LAST> a;
}

  类模板D只有一个参数为void*的构造器,而只有0才能被合法转换为void*。1994年,Erwin Unruh采用Metaware 编译器编译出错信息如下(以及其它一些信息,简短起见,它们被删除了):

| Type `enum{}′ can′t be converted to txpe `D<2>′ ("primes.cpp",L2/C25).
| Type `enum{}′ can′t be converted to txpe `D<3>′ ("primes.cpp",L2/C25).
| Type `enum{}′ can′t be converted to txpe `D<5>′ ("primes.cpp",L2/C25).
| Type `enum{}′ can′t be converted to txpe `D<7>′ ("primes.cpp",L2/C25).

  如今,上面的代码已经不再是合法的C++程序了。以下是Erwin Unruh亲手给出的修订版,可以在今天符合标准的C++编译器上进行编译:

// Prime number computation by Erwin Unruh

template <int i> struct D { D(void*); operator int(); };

template <int p, int i> struct is_prime {
enum { prim = (p==2) || (p%i) && is_prime<(i>2?p:0), i-1> :: prim };
};

template <int i> struct Prime_print {
Prime_print<i-1> a;
enum { prim = is_prime<i, i-1>::prim };
void f() { D<i> d = prim ? 1 : 0; a.f();}
};

template<> struct is_prime<0,0> { enum {prim=1}; };
template<> struct is_prime<0,1> { enum {prim=1}; };

template<> struct Prime_print<1> {
enum {prim=0};
void f() { D<1> d = prim ? 1 : 0; };
};

#ifndef LAST
#define LAST 18
#endif

main() {
Prime_print<LAST> a;
a.f();
}

  在GNU C++ (MinGW Special) 3.2中编译这段程序时,编译器将会给出如下出错信息(以及其它一些信息,简短起见,它们被删除了):

Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 17]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 13]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 11]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 7]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 5]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 3]'
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 2]'

  这个例子展示了可以利用模板实例化机制于编译期执行一些计算。这种通过模板实例化而执行的特别的编译期计算技术即被称为模板元编程。

  顺便说一句,因为编译器的出错信息并未被标准化,所以,如果你在Visual C++、Borland C++等编译器上看不到这么详细的出错信息,请不必讶异。

共5页。 1 2 3 4 5 :

关注此文的读者还看过:

返回开发频道首页

共5页。 12345下一页

软件频道最新更新

热点推荐

天极服务|关于我们|About us|网站律师|RSS订阅|友情合作|加入我们|天极动态|网站地图|意见反馈|MSN/QQ上看天极
Copyright (C) 1999-2012 Yesky.com, All Rights Reserved 版权所有 天极网络