本文为第三部分,目录请参阅概述部分: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:右值引用的更多相关文章

  1. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

    本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...

  2. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part8:Perfect Forwarding(完美转发):解决方案

    本文为第八部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  3. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part6:Move语义和编译器优化

    本文为第六部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  4. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?

    本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  5. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part4:强制Move语义

    本文为第四部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 强制Move语义 众所周知,正如C++标准的第一修正案所陈述:“委 ...

  6. 「翻译」Unity中的AssetBundle详解(二)

    为AssetBundles准备资源 使用AssetBundles时,您可以随意将任何Asset分配给所需的任何Bundle.但是,在设置Bundles时,需要考虑一些策略.这些分组策略可以使用到任何你 ...

  7. 「翻译」Unity中的AssetBundle详解(一)

    AssetBundles AssetBundle是一个存档文件,其中包含平台在运行时加载的特定资产(模型,纹理,预制,音频剪辑,甚至整个场景).AssetBundles可以表示彼此之间的依赖关系;例如 ...

  8. Linux 小知识翻译 - 「协议(protocol)」

    对于理解服务器和网络来说,「协议」是不可缺少的概念. 「协议(protocol)」有「规则,规定」的意思. 实际上「协议」的函数很广,在通信领域,「协议」规定了「在通信时,什么样的情况下,以什么样的顺 ...

  9. 「MoreThanJava」Day 7:接口详解

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

随机推荐

  1. 【NCDC数据】获取 hadoop权威指南3中的NCDC数据

    vi getNcdcBigData.sh 内容如下: #!/bin/bash for i in {1901..2014} do cd /home/xxxx/hapood/ncdc wget --exe ...

  2. bzoj4709 [jsoi2011]柠檬

    Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N  ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们 ...

  3. QT显示中文的几个问题

    最近用QT,需要在界面上显示中文,发现QT无法直接在代码中写中文,只能通过曲线救国的方式,比如用QT语言家,QTextCodec的fromloca8bit 研究了半天,终于明白了一些编码的问题 1.V ...

  4. 【maven】将jar安装到maven本地仓库

    Maven 安装 JAR 包的命令是:  mvn install:install-file -Dfile=jar包的位置 -DgroupId=上面的groupId -DartifactId=上面的ar ...

  5. 使用eclipse和maven创建activiti项目基础配置

    项目组最近的项目使用到了activiti工作流,到处查找了一些资料后,初步完成任务.但是我所做的事只是在搭好的环境中调用接口和方法操作,因此自己尝试着也从搭建环境入手,以下是成功实现以后的记录. 实现 ...

  6. Nginx_地址重写(rewrite)_日志管理(log_format)_压缩输出_Nginx设定限速_Nginx设置反向代理及反向代理缓存

    Nginx地址重写 Nginx rewrite rewrite语法规则1).变量名可以使用 "=" 或 "!=" 运算符~ 区分大小写~* 不区分大小写^~ 禁 ...

  7. svn在linux下的使用(转)

    ubuntu命令行模式操作svn 首先要安装SVN客户端到你的系统才能操作各种命令 apt-get install subversion 1.将文件checkout到本地目录 svn checkout ...

  8. shell中实现自动登录(bash环境脚本中)

    自己的脚本: #!/bin/bash expect  -c  "     set timeout 3600;     spawn su -;     expect *assword:*;  ...

  9. 【转】select和epoll模型的差异

    http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...

  10. Build常见错误

    1.ant 解决com.sun.tools.javac.Main is not on the classpath的问题 在ant打包时报错: 解决com.sun.tools.javac.Main is ...