我用C++模板编写了一个判断偶数/奇数的代码。
#include <iostream>
template <int N, int Mod2=N%2>
struct Print {
Print() {
std::cout << N << std::endl;
}
};
template <int N>
struct Print<N, 0> {
Print() {
std::cout << "Even!" << std::endl;
}
};
template <int N>
struct Print<N, 1> {
Print() {
std::cout << "Odd!" << std::endl;
}
};
template <int N>
struct EvenOdd {
EvenOdd() {
EvenOdd<N+1>();
Print<N>();
}
};
template <>
struct EvenOdd<10> {
EvenOdd() {
std::cout << "Hey!" << std::endl;
}
};
int main()
{
EvenOdd<0>();
return 0;
}
此代码输出:
$ ./a.out
Hey!
Odd!
Even!
Odd!
Even!
Odd!
Even!
Odd!
Even!
Odd!
Even!
我预测到EvenOdd ::EvenOdd()//=>“嘿!”最后被调用。但是,这是错误的。
为什么会“嘿!”首先输出?
最佳答案
此行为与模板无关。这是基本的递归。您在打印之前递归实例化EvenOdd
。因此,第一个打印任何内容的实例是最里面的实例,即EvenOdd<10>
。
这是发生的情况:EvenOdd<0>
所做的第一件事是实例化EvenOdd<1>
。仅当完成时,它才调用Print<0>
。直到EvenOdd<1>
实例化了EvenOdd<2>
并打印完毕,该操作才完成:
EvenOdd<0>
EvenOdd<1>
EvenOdd<2>
EvenOdd<3>
EvenOdd<4>
EvenOdd<5>
EvenOdd<6>
EvenOdd<7>
EvenOdd<8>
EvenOdd<9>
EvenOdd<10>
std::cout << "Hey!" << std::endl;
Print<9>
Print<8>
Print<7>
Print<6>
Print<5>
Print<4>
Print<3>
Print<2>
Print<1>
Print<0>