栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

《Effective Modern C++》学习笔记 - Item 24: 区分万能引用和右值引用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《Effective Modern C++》学习笔记 - Item 24: 区分万能引用和右值引用

T&& 有两种含义:

    右值引用,只能绑定到右值上。万能引用(作者称为 “universal references” ),可以绑定到任何类型的变量上,包括左值或右值,const 或 non-const,volatile 或 non-volatile,以及以上的任何组合。

万能引用出现在两个情景中:

    模板函数的参数, 形式为:

    template
    void f(T&& param); // param is a universal reference
    

    auto 变量推导,形式为:

    auto&& var2 = var1; // var2 is a universal reference
    

万能出现的必要条件是存在类型推导。如果看到了不存在类型推导的 T&&,那么就是右值引用,例如:

void f(Widget&& param); 	// no type deduction;
 							// param is an rvalue reference
Widget&& var1 = Widget(); 	// no type deduction;
 							// var1 is an rvalue reference

除了存在类型推导,万能引用还要求引用出现的形式必须为 T&&,T 不能是任何复合类型或带修饰的类型。以下例子也为右值引用而非万能引用:

template
void f(std::vector&& param); 	// param is an rvalue reference

template
void f(const T&& param); 			// param is an rvalue reference

即使在模板函数中看到了 T&& 参数,也不能立刻敲定其为万能引用,因为在模板中不保证会存在类型推导。例如对于 STL 中的 std::vector:

template> 	// from C++
class vector { 										// Standards
public:
 void push_back(T&& x);
};

push_back() 的参数虽然是 T&& 的形式,但这里没有类型推导,因为 push_back() 必须依赖于一个已经实例化的 vector 而存在,vector 实例化时就已经确定了 T 的类型。调用时,参数 T&& 已经确定为某个具体类型(如 int&&),是右值引用而非万能引用。相反,vector 的另一个成员函数 emplace_back 就会进行类型推导,其形式如下:

template> 	// still from
class vector { 										// C++ Standards
 template 
 void emplace_back(Args&&... args);
};

注意这里的模板参数 Args 与 vector 的模板参数 T 无关。

auto 的情形显然符合以上条件:显然存在类型推导,并且形式正确(auto&&)。

本 Item 的所有内容都是 “谎言”(高情商:是一种抽象),其底层的真相被称为 引用折叠(reference collapsing),在 Item 28 进行讨论。不过这种抽象对于正确理解源码(我看到的 T&& 只能绑定到右值还是任何对象?)很有帮助。(也有助于理解后面 Item 25 和 Item 26 的内容)

总结
    如果一个模板函数的参数的形式为 T&&,且类型 T 涉及推导,或者一个对象是由 auto&& 声明,那个参数或对象就是万能引用。如果类型声明的形式不恰好是 type&&,或者没有涉及类型推导,那么 type&& 就是一个右值引用。万能引用由右值对象初始化时,就是右值引用;由左值对象初始化时,就是左值引用。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/738531.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号