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

The difference is that this code must be instantiated at compile time, probably giving the optimiser better chance to notice that it's just a long sequence of multiplications.

It's really mainly guesswork about the optimiser implementation. It might be better at inlining different template instantiations (because that's how templates are often used) than at inlining recursion (where it needs to discover the stop condition statically) or unrolling loops.

于 2013-05-25T10:14:24.113 に答える