ParamType是一个指针或引用,但不是通用引用
template<typename T>
void f(T& param); //param是一个引用
int x=27; //x是int
const int cx=x; //cx是const int
const int& rx=x; //rx是指向作为const int的x的引用
f(x); // x是int
f(cx); // cx是const int
f(rx); // rx是指向作为const int的x的引用
因为模板参数并未指定是const修饰,所以外层传递的是什么类型,函数内则使用的是什么类型
template<typename T>
void f(const T& param); //param现在是reference-to-const
int x = 27; //如之前一样
const int cx = x; //如之前一样
const int& rx = x; //如之前一样
f(x); //T是int,param的类型是const int&
f(cx); //T是int,param的类型是const int&
f(rx); //T是int,param的类型是const int&
模板参数指定是const修饰,无论外层是什么,函数内都是统一被const修饰
ParamType是一个通用引用
template<typename T>
void f(T&& param); //param现在是一个通用引用类型
int x=27; //如之前一样
const int cx=x; //如之前一样
const int & rx=cx; //如之前一样
f(x); //x是左值,所以T是int&,
//param类型也是int&
f(cx); //cx是左值,所以T是const int&,
//param类型也是const int&
f(rx); //rx是左值,所以T是const int&,
//param类型也是const int&
f(27); //27是右值,所以T是int,
//param类型就是int&&
ParamType既不是指针也不是引用
int x=27; //如之前一样
const int cx=x; //如之前一样
const int & rx=cx; //如之前一样
f(x); //T和param的类型都是int
f(cx); //T和param的类型都是int
f(rx); //T和param的类型都是int
什么都不是的情况下,都是一份新的拷贝,并且默认是对应的数据类型
数组实参
template<typename T>
void f(T param); //传值形参的模板
f(name); //T和param会推导成什么类型?
f(name); //name是一个数组,但是T被推导为const char*
template<typename T>
void f(T& param); //传引用形参的模板
这时候,T会被推导为真正的数组
内置数组和std::array的区别:
array可以使用拷贝和赋值的形式进行初始化,内置数组不能直接使用拷贝和赋值
array是一种容器类型,它支持一系列容器操作
函数实参
void someFunc(int, double); //someFunc是一个函数,
//类型是void(int, double)
template<typename T>
void f1(T param); //传值给f1
template<typename T>
void f2(T & param); //传引用给f2
f1(someFunc); //param被推导为指向函数的指针,
//类型是void(*)(int, double)
f2(someFunc); //param被推导为指向函数的引用,
//类型是void(&)(int, double)
- 在模板类型推导时,有引用的实参会被视为无引用,他们的引用会被忽略
- 对于通用引用的推导,左值实参会被特殊对待
- 对于传值类型推导,const和/或volatile实参会被人为是non-const和non-volatile
- 在模板类型推导时,数组名或者函数名实参会退化为指针,除非它们被用于初始化引用