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

  • 相关阅读:
    复利软件单利及期望值的实现
    实验0 了解和熟悉操作系统
    关于《软件工程》的读后感
    评论
    一个完整的大作业
    数据结构化与保存
    爬取所有校园新闻
    用requests库和BeautifulSoup4库爬取新闻列表
    中文词频统计及词云制作
    组合数据类型练习,英文词频统计实例
  • 原文地址:https://www.cnblogs.com/harrywong/p/rvalue-references.html
Copyright © 2011-2022 走看看