//一、
template<typename T> void f(T);
template<typename T> void g(T&);
double x[20];
int const seven=7;
f(x);//非引用参数:T是double*
g(x);//引用参数:T是double[20]
f(seven);//非引用参数:T是int
g(seven);//引用参数:T是int const
f(7);//非引用参数:T是int
g(7);//引用参数:T是int =》错误:不能把7传递给int &
//注意:对于引用参数,绑定到该参数的实参是不会进行decay的。
//decay:时一个概念,指的是从数组和函数类型到指针类型的
//某些构造不能作为演绎的上下文,例如
//受限的类型名称,例如:Q<T>::X
//除了非类型参数之外,模板参数还包含其他成分的非类型表达式。例如
//诸如,S<I+1> 就不能用来演绎I
//二、特殊情况的演绎
//存在两种特殊情况,其中用于演绎的实参-参数对(A-P)并不是分别来自
//与函数调用的实参和函数模板的实参。
//1.出现在去函数参数模板的时候。例如:
template<typename T>
void f(T,T);
void (*pf)(char,char)=&f;
//2.转型运算符和模板一起出现时
class S{
public:
template<typename T,int N> operator T[N]&();
}
void f(int(&)[20])
void g(S s)
{
f(s);
}
//试图把S转型为int(&)[20];因此,类型为int[20],而类型P为T[N],于是,用
//类型int替换T,用20替换N后该演绎就是成功的。