本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker

该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scott Meyers推荐,全文共分11个部分,我将利用业余时间,分别翻译。

受笔者水平所限,可能叙述会出现些许问题,还望多多指正。

部分名词为了保持含义和方便理解,并未翻译成中文,有的在括号内给出了常见的中文翻译。


目录

  1. 概述
  2. Move语义
  3. 右值引用
  4. 强制Move语义
  5. 右值引用就是右值吗?
  6. Move语义和编译器优化
  7. Perfect Forwarding(完美转发):问题
  8. Perfect Forwarding(完美转发):解决方案
  9. 右值引用和异常
  10. Implicit Move情况
  11. 鸣谢和深入阅读

概述

右值引用是随着C++11标准被引入的一项C++特性。造成右值引用比较难于理解的地方在于:当你刚开始接触它的时候,比较难以搞清楚它存在的目的或者它将要解决什么样的问题。因此,我不会直接阐述什么是右值引用。相反,我会从将要被它解决的问题开始,然后给出是如何通过利用右值引用解决这些问题的。这样,右值引用的定义将会比较合理、自然的呈现给你。

右值引用至少将解决如下两个问题:

  1. 实现Move语义(aka. Move Semantics)
  2. Perfect forwarding(完美转发)

如果你对这些问题并不熟悉,不要担心。下面将会详细解释它们。我们先从Move语义开始。但在开始之前,我需要先提醒你C++中什么是左值(lvalues)和右值(rvalues)。想要给出一个严谨的定义是非常困难的,但是下面的解释对于目的来说已经足够了。

原始的关于左值右值的定义在早期的C是这样的:一个左值是一个可能出现在一个赋值左手边或右手边的表达式e。右值则是只能出现在一个赋值右手边的表达式。举例:

  1. int a = ;
  2. int b = ;
  3.  
  4. // a和b都是左值s:
  5. a = b; // ok
  6. b = a; // ok
  7. a = a * b; // ok
  8.  
  9. // a * b 是右值:
  10. int c = a * b; // ok, 右值在赋值的右手边
  11. a * b = ; // error, 右值在赋值的左手边

在C++中,最初这依然可用,也是对于左值和右值辨认的直觉方法。然而,随着C++和它的用户自定义类型引入了一些关于可变性(modifiability)和可转让性(assignability)的微妙变化,导致这个定义不再正确。我们不需要再深入探讨这个问题。接下来是另一份对此的定义,虽说它可能依然经不起推敲,但是可以让你用来处理右值引用:一个左值是一个能够指向内存地址的表达式,并允许我们通过&操作符来获取那块内存地址。一个右值是一个非左值的表达式。举例如下:

  1. // 左值:
  2. //
  3. int i = ;
  4. i = ; // ok, i是左值
  5. int* p = &i; // ok, i是左值
  6. int& foo();
  7. foo() = ; // ok, foo()是左值
  8. int* p1 = &foo(); // ok, foo()是左值
  9.  
  10. // 右值:
  11. //
  12. int foobar();
  13. int j = ;
  14. j = foobar(); // ok, foobar()是右值
  15. int* p2 = &foobar(); // error,不能从右值取址
  16. j = ; // ok, 42是右值

如果你对严谨的右值和左值定义感兴趣,Mikael Kilpeläinen的这份ACCU文章是就这个课题一份比较好的开始。

翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述的更多相关文章

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

    本文为第三部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 右值引用 如果x是任意类型,那么x&&则被称作一个 ...

  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. C++11标准之右值引用(rvalue reference)

    1.右值引用引入的背景 临时对象的产生和拷贝所带来的效率折损,一直是C++所为人诟病的问题.但是C++标准允许编译器对于临时对象的产生具有完全的自由度,从而发展出了Copy Elision.RVO(包 ...

  9. c++11-17 模板核心知识(十)—— 区分万能引用(universal references)和右值引用

    引子 如何区分 模板参数 const disqualify universal reference auto声明 引子 T&&在代码里并不总是右值引用: void f(Widget&a ...

随机推荐

  1. js中的script标签

    在页面中用script标签引入javascript文件(<script type="text/javascript" src="js文件地址">&l ...

  2. jQuery制作视频网站的展示效果

    效果:如图所示,用户可以单击左上角的左右箭头,来控制视频展示的左右滚动. 当单击向右箭头时下面的展示视频会向左滚动隐藏,同时新的视频展示会以滚动方式显示出来.向左同理. css: ;; word-br ...

  3. activiti自定义流程之Spring整合activiti-modeler5.16实例(八):完成个人任务

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  4. 《黄聪:手机移动站SEO优化教程》3、如何禁止百度对PC网站进行自动转码

    视频地址:http://v.youku.com/v_show/id_XNzE2OTM0NzU2.html

  5. @RequesParam注解源码解析

  6. DBA_Oracle LogMiner分析重做和归档日志(案例)

    2014-08-19 Created By BaoXinjian

  7. ADO.NET(完整修改和查询、实体类,数据访问类)

    一.完整修改和查询 在编写c#语句时需考虑到用户体验,例如在编写修改语句时,需要考虑到输入的内容在数据库中是否能够找到. 中间变量运用. 1.先查 2.执行操作 完整修改语句: bool has = ...

  8. python urllib模块的urlopen()的使用方法及实例

    Python urllib 库提供了一个从指定的 URL 地址获取网页数据,然后对其进行分析处理,获取想要的数据. 一.urllib模块urlopen()函数: urlopen(url, data=N ...

  9. C++程序设计原理与实践

    std_lib_facilities.h和VS下创建C++程序方法:下载 目录: 001. Hello,World!

  10. AD7190学习笔记

    1 建议SCL空闲时会高电平. 2复位:上电后连续输入40个1(时钟周期)复位到已知状态,并等待500us后才能访问串行接口,用于SCLK噪音导致的同步. 3单次转换与连续转换(连续读取):每次转换是 ...