1.理解模板类型推导

86 阅读3分钟

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
  • 在模板类型推导时,数组名或者函数名实参会退化为指针,除非它们被用于初始化引用