zoukankan      html  css  js  c++  java
  • C++11的左值引用与右值引用总结

    概念

    在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的对象,即左值持久,右值短暂

    以上的定义来自于C++Primer(5th)第121页和第471页。可能令人困惑,看了接下来的例子就明白了

    1. int &&rr1 = 42;//正确,字面常量是右值  
    2. int &&rr2 = rr1;//错误,表达式rr1是左值  

    特性中的应用

        decltype关键字

            使用关键字decltype的时候,左值和右值有所不同。如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型,例如,假定p的类型是int*,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整型指针的指针。

        lambda表达式

            lambda表达式是形如auto f = [ ]{ }的函数。

            lambda可指定其捕获列表的类型,[&]表示捕获列表采用隐式引用捕获方式lambda函数体中所使用的来自所在函数的实体都采用引用方式使用,[=]表示采用值捕获方式。

    1. /*f1的sz是隐式值捕获,f2的sz是隐式引用捕获  
    2. auto f1 = [=](const string &s)  
    3.       { return s.size() >=sz; }  
    4. auto f2 = [&](const string &s)  
    5.       { return s.size() >=sz; }  

        拷贝控制

        移动构造函数使用右值引用的形参

    1. class Foo  
    2. {  
    3.    //移动构造函数  
    4.    Foo(Foo&&);  
    5. };  

        引用折叠和实参推断

        实参推断,按照实参和形参匹配的规则。
        引用折叠:
               通常情况下,我们不能将一个右值引用绑定到一个左值上,但是C++语言在正常绑定规则外定义了两个例外规则,允许这种绑定。
        第一个例外规则影响右值引用的参数推断如何进行:当我们将一个左值传递给函数的右值引用参数,且此右值引用指向模板类型参数(如T&&),编译器推断模板类型参数为实参的左值引用类型。
    1. //编译器推断T类型是int&(左值引用),而非int  
    2. template <typename T> void f(T&&);  
    3. int i = 0;  
    4. f(i);  

        引用折叠:在所有情况下(除了一个例外),引用会折叠成一个普通的左值引用类型。

        

    [html] view plain copy
    1. 即:对于一个给定类型X  
    2. <ol>  
    3. <li>X& & ,X& && ,X&& &都折叠成类型X&<li>  
    4. <li>类型X&& &&折叠成X&&<li>  
    5. </ol>  
        注:引用折叠只能应用于间接创建的引用的引用,如类型别名或模板参数。


    这两个规则导致了两个重要结果:

        如果一个函数参数是一个指向模板类型参数的右值引用(如T&&),则他可以被绑定到一个左值。且

        如果实参是一个左值,则推断出的模板实参类型将是一个左值引用,且函数参数将被实例化为一个普通的左值引用参数(T&)

    也暗示了:我们可以将任意类型的实参传递给T&&类型的函数参数。

        函数重载

        重载函数定义两个版本,一个版本接受一个指向const的左值引用,第二个版本接受一个指定非const的右值引用。即可接受所有可转换成当前类型的对象
        
    1. void Foo(const X&);  
    2. void Foo(X&&);  

       我们知道,非常量可以初始化一个底层const,反过来却不行,所以第一种版本可以接收任何能转换成类型X的任何对象。第二种版本只可以传递非const右值,由于精确匹配规则,传递非const右值时,会调用第二种版本,尽管第一种版本也可以接受。

       一般来说,我们不需要为函数操作定义接受一个const X&&或是一个普通的X&参数的版本。当我们希望从实参“窃取‘数据时,通常传递一个右值引用。为了达到这一目的,实参不能使const的。类似的,从一个对象进行拷贝的操作,不应该改变该对象,因此,通常不需要定义一个接受一个普通的X&参数的版本。

  • 相关阅读:
    [转]asp.net页面缓存技术
    UL和LI在div中的高度的IE6下兼容性
    jquery制作的横向图片滚动带横向滚动条TackerScroll
    电脑可以上网,但是qq登陆不上去?
    Introduction to discrete event system学习笔记4.6
    Introduction to Discrete event system学习笔记4.9
    Introduction to discrete event systemsstudy 4.5
    Symbolic synthesis of obserability requirements for diagnosability B.Bittner,M.Bozzano,A.Cimatti,and X.Olive笔记4.16
    Introduction to discrete event system学习笔记4.8pm
    Introduction to discrete event system学习笔记 4.8
  • 原文地址:https://www.cnblogs.com/golaxy/p/9212897.html
Copyright © 2011-2022 走看看