• 左值,右值,右值引用,std::ref(),std::reference_wrapper


    中文标准库:值类别 | 值类别的翻译

    转载:C++中的左值和右值 | 转载:C++中的右值引用和移动

    一、左值(lvalue):

    简单的来说,能取地址的变量一定是左值,有名字的变量也一定是左值,最经典的void fun(p&& shit),其中shit也是左值,因为右值引用是左值(所以才会有move,forward这些函数的产生,其中move出来一定是右值,forward保持变量形式和之前的不变,就是为了解决右值引用是左值的问题)。至于为什么不能把等号左边看成左值,因为在C++中,等号是可以运算符重载的,等号完全可以重载成为等号左边为右值的形式。

    左值是可以取地址的,这也是区分左值和右值的唯一正确的标志

    注意:字符串是左值,字面值常量是右值。例如:"Hello World!"是左值,666,9.9,true,false,nullptr都是纯右值

    二、右值(rvalue):

    当函数返回一个值时编译器会创建一个零时且完整的对象,这个对象就是一个右值

    • prvalue(纯右值):

    纯右值是传统右值的一部分,纯右值是表达式产生的中间值,不能取地址

    • rvalue(右值):

    和左值不同,右值不可以取地址,右值不能在内建等号的左边,如果运算符重载右值是可以在等号左边的

    三、消亡值(xvalue):

    本质上,消亡值就是通过右值引用产生的值。右值一定会在表达式结束后被销毁,比如return x(x被copy以后会被销毁), 1+2(3这个中间值会被销毁)。

    四、右值引用

    右值引用用&&表示,字面意思就是以引用传递(而非值传递)的方式使用右值

    和声明左值引用一样,右值引用也必须立即进行初始化操作,且只能使用右值进行初始化,例如:

    int num = 10;
    //int && a = num;  //错误,右值引用不能初始化为左值
    int && a = 10;
    

    五、引用和std::ref以及std::cref

    转载:std::move、std::ref和std::bind

    std::ref只是尝试模拟引用传递,并不能真正变成引用,在非模板情况下,std::ref根本没法实现引用传递,只有模板自动推导类型时,ref能用包装类型reference_wrapper来代替原本会被识别的值类型,而reference_wrapper能隐式转换为被引用的值的引用类型。std::ref主要是考虑函数式编程如std::bind)在使用时,是对参数直接拷贝,而不是引用。比如thread的方法传递引用的时候,必须外层用ref来进行引用传递,否则就是浅拷贝。

    std::ref用于包装按引用传递的值。std::cref用于包装按const引用传递的值

    六、std::reference_wrapper

    转载:引用传参与REFERENCE_WRAPPER

    七、常引用、引用、传引用、传值

    引用本质只是另一个对象的别名。对引用别名的操作即是对本身变量的操作。

    常引用只能指向一个常量对象,不能指向另一个常量对象。

  • 相关阅读:
    c#驱动操作mongodb辅助类MongoDBHelper
    c#多线程lock无效
    利用Aspose.Words将html转成pdf和将html转成word
    前后端值映射的问题
    本机部署流程详解
    Git 安装配置手册
    js对象数组(JSON) 根据某个共同字段 分组
    jquery中的$.fn的用法
    JSON.parse()与JSON.stringify()的区别
    添加编辑 时 数据不可重复验证
  • 原文地址:https://www.cnblogs.com/mmmmmmmmm/p/15946600.html
Copyright © 2020-2023  润新知