翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用
本文为第三部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html。
右值引用
如果x是任意类型,那么x&&则被称作一个对x的右值引用(rvalue reference)。为了更好区分,原来的引用x&现在也被称作左值引用(lvalue reference)。
一个右值引用是一种同原始引用x&的行为非常类似的类型,但是有一些特例。最重要的一个就是当面临方法重载决议的时候,左值倾向于旧式的左值引用,而右值偏向于新的右值引用。
void foo(X& x); // 左值引用重载
void foo(X&& x); // 右值引用重载 X x;
X foobar(); foo(x); // 参数是左值,调用 foo(X&)
foo(foobar()); // 参数是右值,调用 foo(X&&)
所以它的要点在于:
右值引用允许一个方法在编译时通过重载决议做出选择,基于:”我是被一个左值还是右值调用?“
你可以基于此规则重载任何方法,就像如下所示。但是在绝大多数情况下,这种形式的重载应该只出现在拷贝构造函数和赋值操作符中,为了实现Move语义。
X& X::operator=(X const & rhs); // 常规的实现
X& X::operator=(X&& rhs)
{
// Move语义,交换this和rhs的内容
return *this;
}
实现一个基于右值引用的拷贝构造函数的重载也是类似的。
要点:通常第一眼看上去正确的其实依然有些小瑕疵,这在C++中是经常发生的。事实证明,在某些情况下,在上面对拷贝赋值操作符的实现中,将this和rhs的内容简单的交换,并没有足够好。我们将在第四节「强制Move语义」中继续讨论这个问题。
备注:如果你实现
void foo(X&);而不是
void foo(X&&);那么当然行为表现并没有改变:
foo可以被左值调用,但是不能被右值调用。如果你实现
void foo(X const &);而不是
void foo(X&&);那么依然,行为表现依然没有变化,
foo可以被左值和右值调用,但是想要区分左值和右值是不可能的。这一点只有在如下实现情况下才可行
void foo(X&&);同样的,最后如果你实现
void foo(X&&(;但是既不是
void foo(X&);和
void foo(X const &);那么,根据最终版本的C++11,
foo可以被右值调用,但是如果试着用一个左值去调用它的话,将会触发一个编译器错误。
翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用的更多相关文章
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述
本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案
本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化
本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part4:强制Move语义
本文为第四部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 强制Move语义 众所周知,正如C++标准的第一修正案所陈述:“委 ...
- 「翻译」Unity中的AssetBundle详解(二)
为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...
- 「翻译」Unity中的AssetBundle详解(一)
AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...
- Linux 小知识翻译 - 「协议(protocol)」
对于理解服务器和网络来说,「协议」是不可缺少的概念. 「协议(protocol)」有「规则,规定」的意思. 实际上「协议」的函数很广,在通信领域,「协议」规定了「在通信时,什么样的情况下,以什么样的顺 ...
- 「MoreThanJava」Day 7:接口详解
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
随机推荐
- php 查询出来的字段名全是小写或者大写
PHP PDO预定义常量 PDO::CASE_LOWER -- 强制列名是小写PDO::CASE_NATURAL -- 列名按照原始的方式PDO::CASE_UPPER -- 强制列名为大写 修改此参 ...
- 使用mongo-java-driver3.0.2.jar和mongodb3.0在java代码中的用户验证4
以下是使用mongo-java-driver3.0.2.jar和mongodb3.0.4在java代码中的用户验证: ServerAddress sa = new ServerAddress(host ...
- Chrome安装FlashPlayer Debug
首先: 在谷歌浏览器上打开chrome://plugins 找到 Adobe Flash Player 然后将谷歌自带的版本停用,如果已经安装了for Netscape版,则会显示另外一个版本.(建议 ...
- communication ports in DOS systems:
: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7,COM8, COM9, LPT1, LPT2, LPT3, LPT4, L ...
- POJ 1986 DIstance Query LCA水题
给出一棵树,对于每一个询问,给出2个节点,输出2个节点的距离. 输入中有字母,那个是没有用的,不用管. 思路: 0.选择编号为1的节点作为树的root (注意:有些题的边是单向的,这时候我们要根据节点 ...
- sql中实现split()功能
http://www.cnblogs.com/yangyy753/archive/2011/11/23/2260618.html 数据库中,总是遇到一些字段内容,想根据某个标识截取一下字符串,可是都想 ...
- 专注于提高“人肉测试”效率,Bugtags已完成600万元天使轮融资
导语:近日,专注于移动测试的缺陷发现及管理工具“Bugtags”创始人张磊独家透露,Bugtags已完成600万元天使轮投资,投资方为高捷资本. 近日,专注于移动测试的缺陷发现及管理工具“Bugtag ...
- 利用mysql-proxy 代理无法迁移数据库
一.什么是数据库迁移? 随着业务的增长或机器老化等原因,不可避免会碰到将数据库从一台机器迁移到另一台机器(集群)的问题.数据库迁移可分为冷迁(离线)和热迁(在线实时). 二.如何无缝迁移? 以旧库 1 ...
- c#程序中使用"like“查询access数据库语句的问题
在写使用access数据库的c#程序过程中,遇到各种莫名奇妙的问题.例如使用"like"进行模糊查询,在access查询视图中要使用"*"做模糊匹配(sql中是 ...
- 离线安装PM2
因为要部署应用的机器没有公网连接,所以直接npm install pm2是不可能了, 简单记录一下怎么离线安装pm2 首先,找一台可以在线安装pm2的机器 执行 npm install pm2 -g ...