您倾向于只看到一种做事方式的原因是,人们实际使用模板元编程的事情通常在算法上是微不足道的——它们只是看起来很复杂,因为它们与大量的黑客行为和C++ 模板语法的怪异之处。
但有时(正如史蒂夫·杰索普的回答所示)确实有多种算法可以计算某些东西,您可以使用模板来实现其中的任何一种。
作为另一个例子,这里有两种方法来评估pow(a,b)(对于小整数参数):
很明显:
// ----- Simple Way -----
template <int A, int B>
struct PowA {
typedef PowA<A,B-1> next;
enum {
value = A * next::value,
recursion_count = 1 + next::recursion_count
};
};
template <int A> struct PowA<A, 1> { enum { value = A, recursion_count = 0 }; };
template <int A> struct PowA<A, 0> { enum { value = 1, recursion_count = 0 }; };
Slightly less obvious:
// ----- Less Simple Way -----
template <int A, int B, int IsOdd> struct PowHelper;
template <int A> struct PowHelper<A, 0, 0> { enum { value = 1, recursion_count = 0 }; };
template <int A> struct PowHelper<A, 1, 1> { enum { value = A, recursion_count = 0 }; };
template <int A, int B>
struct PowHelper<A, B, 1> {
typedef PowHelper<A, B-1, 1> next;
enum {
value = A * next::value,
recursion_count = 1 + next::recursion_count
};
};
template <int A, int B>
struct PowHelper<A, B, 0> {
typedef PowHelper<A, B/2, ((B/2)&1)> next;
enum {
x = next::value,
value = x*x,
recursion_count = 1 + next::recursion_count
};
};
template <int A, int B>
struct PowB {
typedef PowHelper<A,B,(B & 1)> helper;
enum {
value = helper::value,
recursion_count = helper::recursion_count
};
};
还有一些代码让你检查一下:
// ----- Test -----
#include <iostream>
int main(int argc, char* argv[]) {
#define CHECK(X,Y) \
std::cout << ("PowA: " #X "**" #Y " = ") << \
PowA<(X),(Y)>::value << " (recurses " << \
PowA<(X),(Y)>::recursion_count << " times)" << std::endl; \
std::cout << ("PowB: " #X "**" #Y " = ") << \
PowB<(X),(Y)>::value << " (recurses " << \
PowB<(X),(Y)>::recursion_count << " times)" << std::endl;
CHECK(3,3)
CHECK(2,8)
CHECK(7,3)
CHECK(3,18)
#undef CHECK
return 0;
}