小学学校网站建设计划,黄桃图片友情链接,网站菜单导航怎么做的,软文推广方法万能引用是一种可以同时接受左值或右值的引用#xff0c;它的形式是T#xff0c;其中T是一个模板参数。万能引用不是C的一个新特性#xff0c;而是利用了模板类型推导和引用折叠的规则来实现的功能。
模板类型推导
模板类型推导是指在调用一个模板函数时#x…万能引用是一种可以同时接受左值或右值的引用它的形式是T其中T是一个模板参数。万能引用不是C的一个新特性而是利用了模板类型推导和引用折叠的规则来实现的功能。
模板类型推导
模板类型推导是指在调用一个模板函数时编译器会根据传入的实参来推导出模板参数的类型。例如
templateclass T
void f(T t) {}int x 10; // x 是左值
f(x); // 调用f时T被推导为int注意而不是int
f(20); // 调用f时T被推导为int之所以调用f(x)时T被推导为int这是因为如果实参是一个左值那么它会被当作一个右值来处理除非模板参数的形式是T或者T。例如
templateclass T
void h(T t) {}templateclass T
void i(T t) {}templateclass T
void j(T t) {}int x 10; // x 是左值
h(x); // 调用h时T被推导为int
i(x); // 调用i时T被推导为int
j(x); // 调用j时T被推导为int你可以看到在调用h和i时T都被推导为int而在调用j时T才被推导为int。这是因为在j的模板参数中使用了符号这样就触发了万能引用的机制。
当模板参数的形式为T的时候:
templateclass T
void k(T t) {}int x 10; // x 是左值
k(x); // 调用k时T被推导为int
k(20); // 调用k时编译错误因为不能把右值绑定到非常量左值引用上你可以看到在调用k时如果传入一个右值就会发生编译错误。这是因为右值是临时的不能被修改或者延长其生命周期。如果想要让模板函数接受右值可以使用常量左值引用或者右值引用作为模板参数的形式。
引用折叠
引用折叠是指在定义一个引用类型时如果它本身就是一个引用类型那么会发生如下的转换
左值引用 左值引用 左值引用右值引用 右值引用 右值引用左值引用 右值引用 左值引用右值引用 左值引用 左值引用
例如
int x 10; // x 是左值
int r1 x; // r1 是左值引用
int r2 20; // r2 是右值引用// 引入了两个别名类型
using LRef int ;
using RRef int ;LRef r3 r1; // r3 的类型是 LRef 即 int 经过折叠后变为 int
RRef r4 r2; // r4 的类型是 RRef 即 int 经过折叠后变为 int
LRef r5 r2; // r5 的类型是 LRef 即 int 经过折叠后变为 int
RRef r6 r1; // r6 的类型是 RRef 即 int ,经过折叠后变为 int 结合这两个规则我们就可以理解万能引用的工作原理。例如
templateclass T
void g(T t) {}int x 10; // x 是左值
g(x); // 调用g时T被推导为int注意不是int因此t的类型是int // 经过折叠后变为int左值
g(20); // 调用g时T被推导为int注意不是int因此t的类型是int // 经过折叠后仍然是int右值你可以看到在调用g时t既可以绑定到左值上也可以绑定到右值上并且保持了原来实参的属性。这就实现了万能引用。