※ 引述《Clangpp (Clang++)》之铭言:
: 最近一直在看template metaprogramming
: 也看了费式数列的范例,但很多人的介绍也知道这东西很威
: 是turing complete
: 但是小弟我现在还是没什么sense,到底如何将平时的
: 东西改写成这样或是说可以应用在哪方面。
: 到底sense该如何抓??
: 有请高手指教
: 谢谢
这里先来说说我自己的理解,有不对的地方还请各位高手指教:)
简单来说,这玩意就是在编译期做原本运行期在做的事情,你完全可以不需要用到这个技巧而达到同样的功能。
例如原本运行期的OO继承是这样写:
class Base{
public:
virtual void someMethod() = 0;
};
class Derived : public Base{
public:
virtual void someMethod() override{};
};
在运行期呼叫里面的someMethod()的时候需要再去找v-table才有办法定位置该方法。由于所有事情都在运行时期发生,所以会有一些cost存在。(只要该类别任何一个方法宣告virtual就会建立出v-table)
而用template写就变成:
template <class Derived>
class Base{
void someMethod(){
static_cast<Derived*>(this)->someMethodImplement();
};
};
class Derived : Base<Derived>{
public:
void someMethodImplement(){};
};
我们可以看到template的写法把把v-table省略掉了,寻找Derived的动作被移到编译期上执行,因此在运行期会省一些时间。只是缺点在于写不好的话会造成code size膨胀到非常大,而且编译速度也会变慢。为什么呢?这是因为编译器会在编译期帮你把code产生出来,自动产生的code越多,当然code size会越大,而且编译也会变慢。
你能想像你编译出来的exe或lib档大小原本只需要几KB,但却膨胀到MB甚至几GB吗?好啦,这里的比喻可能有点夸张,但系统一大起来的话也不是没有可能。所以写这个要特别注意code bloat的问题。
其实template metaprogramming在标准库里面用的到处都是,要能够驾驭这套工具其实不是很容易,而且学习门槛还蛮高的。我自己也还在学习路上 : )
好处是学会这套的话,在设计高效率的系统上会很有帮助。