5

我了解使用模板创建编译时阶乘计算的著名示例,这样就不需要递归运行时计算。在这样的示例中,计算所需的所有值在编译时都是已知的。

但是我遇到了另一个使用模板计算数字幂的示例,我只是不明白这是对类似运行时递归函数的优化:

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,对吧?

对于这样的模板,它们是否具有明显的优势?也许我只是没有看到它。

4

2 回答 2

4

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

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
演示

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

于 2013-05-25T11:23:25.793 回答
0

不同之处在于这段代码必须在编译时实例化,这可能让优化器有更好的机会注意到它只是一长串乘法。

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

于 2013-05-25T10:14:24.113 回答