该模板如何导致运行时递归的编译时优化?

时间:2013-05-25 10:10:22

标签: c++ templates metaprogramming

我理解使用模板创建编译时因子计算的众所周知的示例,这样就不需要递归运行时计算。在这样的示例中,计算的所有必需值在编译时都是已知的。

但是我遇到了另一个使用模板来计算数字功效的例子,我只是不知道这是一个类似运行时递归函数的优化:

template<int n>
inline int power(const int& m) { return power<n-1>(m)*m;}

template<>
inline int power<1>(const int& m) { return m;}

template<>
inline int power<0>(const int& m) { return 1;}

cout << power<3>(m)<<endl;

显然,在此示例中,在编译时无法识别m。因此,在运行时,仍会执行一系列计算,结果与m*m*m基本相同,对吧?

他们对这样的模板有明显的优势吗?也许我只是没有看到它。

2 个答案:

答案 0 :(得分:3)

只有在编译时知道XY时,才能获得模板元编程的优势。示例代码:

template<unsigned int X, unsigned int N>
struct Power { static const unsigned int value = X * Power<X,N-1>::value; };

template<unsigned int X>
struct Power<X,0> { static const unsigned int value = 1; };

用法:Power<X,Y>::value确定X^Y Demo

在您发布的代码中(恰好使用template但不使用元编程!),在编译时只知道Y,并且X作为运行时参数传递。这意味着结果也将在运行时计算,我们必须依赖基于编译器的优化。在这种情况下最好使用std::pow(..)

答案 1 :(得分:0)

不同之处在于此代码必须在编译时实例化,这可能会让优化器更好地注意到它只是一个很长的乘法序列。

这主要是关于优化器实现的猜测。它可能更好地内联不同的模板实例化(因为这是模板经常使用的方式) 在内联递归(需要静态发现停止条件)或展开循环。