C++箴言:谨慎使用模板元编程
这个调用生成的版本。用 iter 和 10 的类型取代 template parameters(模板参数)IterT 和 DistT 之后,我们得到这个:
void advance(std::list<int>::iterator& iter, int d)
问题在突出显示的行,使用了 += 的那行。在当前情况下,我们试图在一个 list<int>::iterator 上使用 +=,但是 list<int>::iterator 是一个 bidirectional iterator(双向迭代器)(参见《C++箴言:为类型信息使用特征类》),所以它不支持 +=。只有 random access iterators(随机访问迭代器)才支持 +=。此时,我们知道我们永远也不会试图执行那个 += 行,因为那个 typeid 检测对于 list<int>::iterators 永远不成立,但是编译器被责成确保所有源代码是正确的,即使它不被执行,而当 iter 不是一个 random access iterator(随机访问迭代器)时 "iter += d" 是不正确的。traits-based(基于 traits)的 TMP 解决方案与此对比,那里针对不同类型的代码被分离到单独的函数中,其中每一个都只使用了可用于它所针对的类型的操作。 TMP 已经被证明是 Turing-complete(图灵完备)的,这意味着它强大得足以计算任何东西。使用 TMP,你可以声明变量,执行循环,编写和调用函数,等等。但是这些结构看起来与其在“常规”C++ 中的样子非常不同。例如,《C++箴言:为类型信息使用特征类》展示了 if...else 条件在 TMP 中是如何通过 templates(模板)和 template specializations(模板特化)被表达的。但那是 assembly-level(汇编层次)的 TMP。针对 TMP 的库提供了一种更高层次的语法,虽然还不至于让你把它误认为是“常规”C++。 为了一窥其它东西在 TMP 中如何工作,让我们来看看 loops(循环)。TMP 中没有真正的 looping construct(循环结构),因此 loops(循环)的效果是通过 recursion(递归)完成的。(如果你对 recursion(递归)感到不舒服,在你斗胆进入 TMP 之前一定要解决它。TMP 很大程度上是一个 functional language(函数性语言),而 recursion(递归)之于 functional language(函数性语言)就像电视之于美国流行文化:是密不可分的。)然而,甚至 recursion(递归)都不是常规样式的,因为 TMP loops 不涉及 recursive function calls(递归函数调用),它们涉及 recursive template instantiations(递归模板实例化)。 TMP 的 "hello world" 程序在编译期间计算一个阶乘。它不是一个很令人兴奋的程序,不过,即使不是 "hello world",也有助于语言入门。TMP 阶乘计算示范了通过 recursive template instantiation(递归模板实例化)实现循环。它也示范了在 TMP 中创建和使用变量的一种方法。看: template<unsigned n> // general case: the value of
给出这个 template metaprogram(模板元程序)(实际上只是单独的 template metafunction(模板元函数)Factorial),你可以通过引用 Factorial<n>::value 得到 factorial(n) 的值。 代码的循环部分出现在 template instantiation(模板实例化)Factorial< |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |