• 翻译「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可以被右值调用,但是如果试着用一个左值去调用它的话,将会触发一个编译器错误。

  • 相关阅读:
    Cocos2dx-背景无限循环播放
    centos 7端口和防火墙
    图片裁剪
    spring-boot图片压缩
    vue cli简介
    spring-boot的配置(实时生效)
    spring-boot打成war包放入tomcat运行
    spring-boot上传图片并访问
    linux链接ssh
    mysql远程访问
  • 原文地址:https://www.cnblogs.com/harrywong/p/rvalue-references.html
Copyright © 2020-2023  润新知