关于术语的问题:
演绎,推导,演推,我也不知道哪个准确,反正就是这个意思
template<int i>
class A
{
public:
static const int a = 3 * A< i - 2>::a * A<i -1>::a;
};
template<>
class A<2>
{
public:
static const int a = 2;
};
template<>
class A<1>
{
public:
static const int a = 1;
};
cout<<A<6>::a<<endl; //请问输出什么
这个稍微有些复杂. 先来看个简单的:
示例1:
template<int i>
class A
{
public:
static const int a = 5 ; // 实例化 a = 5;
}
cout<<A<6>::a<<endl; //请问输出什么
当然是 5 了
示例2:
template<int i>
class A
{
public:
static const int a ;
};
template<int a>
const int A<a>::a =7; // 实例化 a = 7;
cout<<A<6>::a<<endl; //请问输出什么
当然是 7 了
示例3:
template<int i>
class A
{
public:
static const int a = i ;
};
cout<<A<6>::a<<endl;
cout<<A<7>::a<<endl;
输出:
6
7
因为它用这里的常数来 实例化了类模板中的a; 静态常量.
示例4:
template<int i>
class A
{
public:
static const int a = A<i >::a;
};
cout<<A<6>::a<<endl; //输出什么?
答: 编译不过,为什么?因为 A<i> 这里应该是常量表达式 例如: A<i-1>, A<i+1>, A<i+2>...... ,
为什么要为样做呢, 看了下面的或许你就懂了.
示例5:
template<int i>
class A
{
public:
static const int a = A<i -1 >::a;//注意这里的-1 , 这个表达式有点像递归
};
template<>//这个是什么? 这个是递归结束条件 也就是所谓的特化,如果不写 //会导致编译器死掉的,因为它会死循环.
class A<1>
{
public:
static const int a = 1;
};
cout<<A<6>::a<<endl; //输出什么?
输出
1
哪
cout<<A<10>::a<<endl; //输出什么?
还是
1
为什么呢,因为在编译的时候编译器要初始化a ,例如:
cout<<A<6>::a<<endl;
它就从6开始把6带到模板中我们模拟一下它的过程
第一次:
template<6>
class A
{
public:
static const int a = A<6 -1 >::a; // 6-1 = 5
//A<5> 也就是这样的,
};
发现没有A<5> 这样的特化模板,然后呢,怎么办呢?, 我们这里不是有个-1吗, 它就会减1, 减1 后就变成了5 继续演绎它.
第二次
template<5>
class A
{
public:
static const int a = A<5 -1 >::a; // 5-1 = 4
//A<4> 也就是这样的,
};
第三次
A<4>
第四次
A<3>
第五次
A<2>
第六次
A<1>
好了 这次终于找到组织了,A<1>, 还记得我们写的特化模板吗,
template<>
class A<1>
{
public:
static const int a = 1;
};
找到了, 哇塞 找到了耶, 是1, 所以它就以1来实例化它
示例6:
如果
static const int a = A<i -1 >::a;
改为
static const int a = A<i -2 >::a;
cout<<A<6>::a<<endl;
模板是不是还是从6开始演绎呢? 是的 但不是
6 5 4 3 2 1
而是
6 4 2 0 -2 -4..... 这样的,因为这里是-2 .如果找不到终止的偏特化模板它就会死掉
哪如果 + 2呢
6 8 10 12....
哪如果是 * 2呢
6 12 24 48 ......
总之一句话:
static const int a = A<i -2 >::a;
这里的表达式是什么它就,怎么演推
示例7:
template<int i>
class A
{
public:
static const int a = 3 * A<i -1>::a;
};
template<>
class A<1>
{
public:
static const int a = 1;
};
cout<<A<6>::a<<endl;
这里又会输出什么
243
为什么
其实我们说应该先确定终止条件,终止条件是1 ,那就是当i = 2的时候就能满足这个条件:
当i是2的时候:
template<2>
class A
{
public:
static const int a = 3 * A<2 -1>::a; // A<1> 所以这里的 a = 3
};
这个知道了 其它的就好办了.
其它的就是一共多少次了倒着往上把下一层的值 一直 *3
红色为当模板实参值为:
6 81*3 = 243
5 27*3 = 81
4 9*3 = 27
3 3 *3 =9
2 1 * 3 = 3 // 当模板实参为2 时 模板表达式 2-1 = 1 达到了终止条件. 确定了 a的值 为 1
示例 8
template<int i>
class A
{
public:
static const int a = A< i - 2>::a + A<i -1>::a;
};
template<>
class A<1>
{
public:
static const int a = 1;
};
template<>
class A<2>
{
public:
static const int a = 2;
};
cout<<A<6>::a<<endl;//
输出: 13
递归如下:
(6)=f(5)+f(4); = 8 + 5
f(5)=f(4)+f(3); = 5 +3
f(4)=f(3)+f(2); = 3 + 2
f(3)=f(2)+f(1) = 2 + 1= 3
如果把上题变一下
template<int i> struct B { static const int a = B< i - 2>::a + B<i-3>::a; };
template<> struct B<2> { static const int a = 2; };
template<> struct B<1> { static const int a = 1; };
template<> struct B<0> { static const int a = 0; };
cout<<B<10>::a<<endl; //输出 13
注: f 后面的数字加上一个括号 我省略了 f(10) = f10
f10= f8 +f7 = 7 +6
f8= f6+f5 = 4 +3 =7
f7= f5 +f4 = 3 + 3 = 6
f6 = f4+f3 = 3 +1 = 4
f5 = f3+f2 = 1 + 2 =3
f4 = f2+f1 = 3
f3 = f1+f0 = 1+0 =1
规律就是
f(n) = f(表达式一) 运算符 f(表达式二) ...
f(表达式一) = ...
f(表达式二) = ...
不断的分解未知表达式
鸣谢 :群里的大牛们的帮助.
模板元编程递归解析
最新推荐文章于 2022-05-31 18:50:21 发布