分享
 
 
 

the boost c++ metaprogramming:boost c++ 模板元编程(3)

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

1.3. Why metaprogramming?

问一下人们为什么想这么做是有意义的;毕竟,即使像factorial metafunction这样的玩具程序也有些深奥;为了演示类型计算如何应用在工作中,我们再来看一个简单的例子:

下面的代码产生了一个数组,用来容纳另一个数组其元素所有可能的排列组合

// can't return an array in C++, so we need this wrapper

template< typename T >

struct wrapper

{

T x;

};

// return an array of the N! permutations of 'in'

template< typename T >

wrapper< typename permutation_holder<T>::type >

all_permutations(T const& in)

{

wrapper<typename permutation_holder<T>::type> result;

// copy the unpermutated array to the first result element

unsigned const N = sizeof(T) / sizeof(**result.x);

std::copy(&*in, &*in + N, result.x[0]);

// enumerate the permutations

unsigned const result_size = sizeof(result.x) / sizeof(T);

for (T* dst = result.x + 1; dst != result.x + result_size; ++dst)

{

T* src = dst - 1;

std::copy(*src, *src + N, *dst);

std::next_permutation(*dst, *dst + N);

}

return result;

}

factorial的运行期版本在上面的all_permutations中是无法使用的,因为在C++中数组大小必须在编译期计算;然而,另有一些替补方案,我们如何才能避免元编程,最终的结论又是什么呢?

1,我们可以写程序直接解释元数据

在我们的factorial的例子中,数组大小可以是运行期的变量,因而我们能够直接使用运行期的factorial函数,但是这意味着动态分配,而它通常是昂贵的;更进一步,可以改写YACC让它接受一个函数指针,这个指针指向的函数将返回待解析流中的tokens和包含文法描述的字符串;然而,对大多数程序来说,这种方法将导致不可接受的运行期代价:解析器或者是不得不接受不确定的文法,为每一次解析都摸索一遍文法,或者是不得不为每次输入的文法在运行期复制the substantia table-generation和优化已经存在的YACC的工作

2,我们可以用我们自己的计算来代替编译器编译期间的计算

毕竟,传递给all_permutations的数组的大小一直是编译期可知的,因此对用户也是可知的,我们可以要求用户显式的提供结果的类型:

template< typename Result, typename T >

Result all_permutations(T const& input);

这种方法的代价是很明显的:我们放弃了表达能力(通过要求用户显式的指定实现细节)和正确性(通过允许用户指定错误的结果类型);任何一个手工写过解析器表格的人将告诉你,这种方法的不切实际正是YACC存在的原因

在元数据可以以用户其余程序同样的语言来表达的语言,如C++中,表达能力得到了进一步的加强:用户可以直接调用元程序,不需要学习另外的语法,不需要打断自己正常的代码流

因此,元编程的动机来自于下面三个因素的联合:效率,表达能力,正确性;在传统的程序中,一直存在着一股压力,一边是表达能力和正确性,一边是效率,而在元编程世界中,我们挥舞着新的武器:我们能够将表达能力所需要的计算从运行期转移到编译期

1.4. Why a metaprogramming library?

有人可能还想问一下为什么我们需要一个泛型库:

• 质量

适用于通用目的的库的代码,往往也适用于用户的目的,对库的开发者来说,这是中心任务;一般来说,任何C++标准库的实现给出的容器和算法,都要比大量存在的特定工程的实现给出的容器和算法更加灵活,实现的更好,因为库的开发是以它本身为目的的,而不是作为其他应用附带的任务,

对任何给定功能的集中的实现,更容易应用优化和改进

• 复用

比任何库都提供的代码的复用更重要,一个设计良好的泛型库建立了一个concepts和idioms的framework,这些concepts和idioms建立了解决问题的可复用的思维的模型;类似于C++ STL给了我们iterator concepts和function object protocol,Boost MPL提供了type-iterators 和 metafunction class protocol;一个考虑周全的idioms的framework节省了元程序员考虑与手头工作不相关的实现细节的时间,而让他们集中精力在手头问题上

• 可移植性

一个优秀的库可以消除,掩盖丑陋的平台差异;理论上一个元程序库是完全泛型的,不需考虑这些问题,但实际上对模板的支持依然有大量的不一致,即使是标准化四年之后;这或许不应该感到惊奇:C++模板是语言最深远,最复杂的特性,极大的增强了C++元编程的能力

• 有趣

一遍遍的重复同样的idioms是单调乏味的;它使程序员疲劳,降低生产力;更进一步,当程序员感到厌倦时他们会以比慢慢写代码更大的代价写出晦涩的,充满虫子的代码;通常最有用的库是机敏的程序员从海量的重复中提取出的简单的模式;MPL通过消除大量样板代码的重复来帮助程序员减少厌倦;

像人们能够看到的,MPL的开发是由推动了其它库的开发的同样的,实际的,真实世界中的问题推动的;或许这是一种迹象,表明模板元编程已经完成了最后的准备,即将离开深奥的领域,进入每个日常程序员的口头话题

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有