问题
I have difficulties to understand how the following template definition and template specialization definition work? To me, factorial<34>
or factorial<T-1>
look strange!
For example:
factorial<T - 1>::value
means what?
#include <iostream>
template<int T>
struct factorial {
enum { value = factorial<T - 1>::value * T };
};
template<>
struct factorial<1> {
enum { value = 1 };
};
int main()
{
std::cout << factorial<34>::value << std::endl;
}
g++ -o testSTL01 testSTL01.cpp -Wall
testSTL01.cpp: In instantiation of ‘factorial<13>’:
testSTL01.cpp:5:3: instantiated from ‘factorial<14>’
testSTL01.cpp:5:3: instantiated from ‘factorial<15>’
testSTL01.cpp:5:3: instantiated from ‘factorial<16>’
testSTL01.cpp:5:3: instantiated from ‘factorial<17>’
testSTL01.cpp:5:3: instantiated from ‘factorial<18>’
testSTL01.cpp:5:3: [ skipping 11 instantiation contexts ]
testSTL01.cpp:5:3: instantiated from ‘factorial<30>’
testSTL01.cpp:5:3: instantiated from ‘factorial<31>’
testSTL01.cpp:5:3: instantiated from ‘factorial<32>’
testSTL01.cpp:5:3: instantiated from ‘factorial<33>’
testSTL01.cpp:5:3: instantiated from ‘factorial<34>’
testSTL01.cpp:15:29: instantiated from here
testSTL01.cpp:5:3: warning: integer overflow in expression
start to run the app ...
0
回答1:
This is an example of template metaprogramming. This program calculates factorial at compile time using recursion. The base of recursion is here:
template<>
struct factorial<1> {
enum { value = 1 };
};
It says that factorial of 1 is 1.
The other template simply says that factorial of a number is that number times factorial minus 1.
template<int T>
struct factorial {
enum { value = factorial<T - 1>::value * T };
};
Since there is really no "calling" in the classic sense, the template instantiates itself with a template argument equal to T-1
calculated at compile time.
P.S. The warning shows that factorial of 34 overflows 32-bit integer.
回答2:
That is not really a question, it's a statement. Template arguments don't have to be types, but they are types in a vast majority of cases, so you may not have seen non-type template arguments before.
That said, factorial<1>
uses the specialization (with value=1
), and factorial<N>
with N > 1 uses the general case, which refers to factorial<N-1>
. That gives you a compile-time evaluation of the factorial (because the templates expand recursively).
But do you have any idea how large the factorial of 34 is? Would you expect that to fit into an integer? (Answers: 295232799039604140847618609643520000000, and no).
来源:https://stackoverflow.com/questions/9098061/meaning-of-factorialt-1-in-template-definition