我用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;
}
Run Code Online (Sandbox Code Playgroud)
此代码输出:
$ ./a.out
Hey!
Odd!
Even!
Odd!
Even!
Odd!
Even!
Odd!
Even!
Odd!
Even!
Run Code Online (Sandbox Code Playgroud)
我预测到了
EvenOdd<10>::EvenOdd() //=> "Hey!"最后被称为.但是,这是错误的.
为什么"嘿!" 首先输出?
此行为与模板无关.这是基本的递归.您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>
Run Code Online (Sandbox Code Playgroud)
您的模板EvenOdd仅显式专用于参数10,所有其他特化的构造函数EvenOdd将模板参数的匿名实例化N+1为其构造函数中的第一个操作.
这意味着EvenOdd构造函数将EvenOdd在任何EvenOdd对象构造PrintObject 之前以递归方式生成直到模板参数10的匿名临时对象.
构造第11个EvenOdd对象导致输出"Hey!",然后Print构造第一个对象.
| 归档时间: |
|
| 查看次数: |
184 次 |
| 最近记录: |