C++ 中的型别推导
1. 模板型别推导
对于以下函数模板和调用
// 函数模板
template<typename T>
void func(ParamType param);
// 调用模板函数
func(expr);
编译器会在编译期通过 expr
推导两个型别:T
和 ParamType
。比如
// 函数模板
template<typename T>
void func(const T& param);
// 模板函数调用
int i = 0;
func(i);
则 T
被推导为 int
,ParamType
被推导为 const int&
。但是,T
的型别推导结果不一定与传递给函数的实参(expr
)的型别一致;T
的型别推导结果不仅依赖实参的型别,还依赖 ParamType
的形式:
ParamType
是个指针或引用,但不是万能引用ParamType
是万能引用ParamType
既不是指针也不是引用
Case 1. ParamType
是个指针或引用,但不是万能引用
- 若
expr
是个引用,则先忽略引用部分,再对expr
的型别和ParamType
的型别进行模式匹配,从而决定T
的型别
// 函数模板
template<typename T>
void func(T& param);
// 调用模板函数
int x = 27;
func(x); // ParamType 推导为 int&,T 推导为 int
const int cx = x;
func(cx); // ParamType 推导为 const int&,T 推导为 const int
const int& rcx = x;
func(rcx); // 先忽略引用,即相当于 func(cx),因此
// ParamType 推导为 const int&,T 推导为 const int
从上述结果我们也可以看到,对象的常量性(constness)会成为 T
的型别推导结果的组成部分,但其引用性(reference-ness,包括左值引用和右值引用)会在型别推导过程中被忽略(当然,只能向右值引用形参传递右值引用实参)
// 函数模板
template<typename T>
void func(const T& param)