• C++中的ravalue学习笔记


    一、学习笔记

    1. A a = 42; 会先以42为参数构造一个A类对象,然后调用拷贝构造函数来构造a,目前编译器优化掉了拷贝构造函数的调用,测试拷贝构造函
    数是没有被调用的,但是其权限不能为private的,即使提供了重载的拷贝构造函数(其它没有调用到的构造函数可以被设置为private的)

    2. 打印出下面两个地址相同,编译器优化过了

    B get() {
        B b1(1);
        cout << &b1 << endl; //地址1
        return b1;
    }
    
    int main() {
        B b = get();
        cout << &b << endl; //地址2
        return 0;
    }

    3. C++11标准引入了右值引用,使用它可以使临时对象的拷贝具有move语意,从而可以使临时对象的拷贝具有浅拷贝般的效率,这样便可以从
    一定程度上解决临时对象的深度拷贝所带来的效率折损。

    4. 区分一个表达式是左值还是右值,最简便的方法就是看能不能够对它取地址:如果能,就是左值;否则,就是右值。
    由于右值引用的引入,C++11标准中对表达式的分类不再是“非左即右”那么简单,不过为了简单地理解,我们暂时只需区分左值右值即可,C++11标准中的分类后面会有描述。

    5. 下面简单地总结了左值引用和右值引用的绑定规则(函数类型对象会有所例外):
    (1)非const左值引用只能绑定到非const左值;
    (2)const左值引用可绑定到const左值、非const左值、const右值、非const右值;
    (3)非const右值引用只能绑定到非const右值;
    (4)const右值引用可绑定到const右值和非const右值。

    6. 右值引用绑定到字面值常量同样符合上述规则,例如:int &&rr = 123;,这里的字面值123虽然被称为常量,可它的类型为int,而不是const int。对此C++03标准文档4.4.1节及其脚注中有如下说明:

    7. 模板参数的推导其实就是形参和实参的比较和匹配,如果形参是一个引用类型(如P&),那么就使用P来做类型推导;如果形参是一个cv-unqualified(没有const和volatile修饰的)右值引用类型(如P&&),并且实参是一个左值(如类型A的对象),就是用A&来做类型推导(使用A&代替A)。

    二、Demo

    struct A {
        A(){} 
    };
    
    A rvalue() {return A();}              // 返回一个非const右值对象
    const A const_rvalue() {return A();}  // 返回一个const右值对象
    
    // void fun() {}
    // typedef decltype(fun) FUN;  // typedef void FUN();
    
    int main()
    {
    
        A lvalue;                             // 非const左值对象
        const A const_lvalue;                 // const左值对象
    
    
        // 规则一:非const左值引用只能绑定到非const左值
        A &lvalue_reference1 = lvalue;         // ok
        A &lvalue_reference2 = const_lvalue;   // error
        A &lvalue_reference3 = rvalue();       // error
        A &lvalue_reference4 = const_rvalue(); // error
    
        // 规则二:const左值引用可绑定到const左值、非const左值、const右值、非const右值
        const A &const_lvalue_reference1 = lvalue;         // ok
        const A &const_lvalue_reference2 = const_lvalue;   // ok
        const A &const_lvalue_reference3 = rvalue();       // ok
        const A &const_lvalue_reference4 = const_rvalue(); // ok
    
        // 规则三:非const右值引用只能绑定到非const右值
        //A &&rvalue_reference1 = lvalue;         // error
        //A &&rvalue_reference2 = const_lvalue;   // error
        //A &&rvalue_reference3 = rvalue();       // ok
        //A &&rvalue_reference4 = const_rvalue(); // error
    
        // 规则四:const右值引用可绑定到const右值和非const右值,不能绑定到左值
        //const A &&const_rvalue_reference1 = lvalue;         // error
        //const A &&const_rvalue_reference2 = const_lvalue;   // error
        //const A &&const_rvalue_reference3 = rvalue();       // ok
        //const A &&const_rvalue_reference4 = const_rvalue(); // ok
    
        // 规则五:函数类型例外
        //FUN       &  lvalue_reference_to_fun       = fun; // ok
        //const FUN &  const_lvalue_reference_to_fun = fun; // ok
        //FUN       && rvalue_reference_to_fun       = fun; // ok
        //const FUN && const_rvalue_reference_to_fun = fun; // ok
    
        return 0;
    }

    参考:https://www.cnblogs.com/opangle/archive/2012/11/19/2777131.html

  • 相关阅读:
    Android6.0权限组申请
    Win10安装程序出现error code 2502 2503
    StartUML2.8破解
    Batchsize与learning rate
    Tensorflow 多gpu训练
    centos7系统时间修复
    服务器安装小结
    caffe与tensorflow中的pooling
    MixConv
    blazeFace
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10632191.html
Copyright © 2020-2023  润新知