博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++11新特性:std::move()和std::forward()
阅读量:7112 次
发布时间:2019-06-28

本文共 1389 字,大约阅读时间需要 4 分钟。

hot3.png

    C++11通过std::move()和std::forward()函数分别实现了左值转右值和完美转发的功能。

    对于std::move(),考虑如下情形:

    void func(int &&args) {

        std::cout << args << std::endl;

    }

    int a = 10;

    func(20);    // ok

    func(a);      // error, 右值引用不能绑定左值

    func(std::move(a));    // ok

    

    对于std::forward(),完美转发,当

    void func(int &arg) {

        std::cout << "func lvalue" << std::endl;
    }

    void func(int &&arg) {

        std::cout << "func rvalue" << std::endl;
    }

    template <typename T>

    void wrapper(T &&args) {
        func(args);
    }

    int main() {

        int a = 10; 

        wrapper(a);

        wrapper(20);

        return 0;

    }
    以上函数输出:

        func lvalue

        func lvalue

    虽然我们调用wrapper()函数时,传入的参数一个是左值,一个是右值,但是最终的输出确都是左值。原因是我们在中间加了一层转发函数wrapper()。

    引用叠加,引用是可以叠加的,对于 T &&a; 叠加规则如下:

    (1)当T类型为 Type 时,a 为 Type &&a,右值引用。

    (2)当T类型为 Type& 时,a为 Type &a,左值引用。

    (3)当T类型为 Type&& 时,a为 Type &&a,右值引用。

   通过引用叠加,分析以上示例可知,调用wrapper()时,wrapper(a) 是调用的原型是 wrapper(int &),是左值调用;wrapper(20)调用的原型是wrapper(int &&),是右值调用。但是在wrapper()函数内部,无论如何,args都是一个左值,在调用func()函数的时候,调用的func()原型总是func(int &)。

    因此,根本原因其实是,右值引用属性不能被转发。所以,C++11提供了std::forward()函数用于完美转发。即,在转发过程中,左值引用在被转发之后仍然保持左值属性,右值引用在被转发之后依然保持右值属性。修改之后的代码如下:

 void func(int &arg) {

        std::cout << "func lvalue" << std::endl;
    }

    void func(int &&arg) {

        std::cout << "func rvalue" << std::endl;
    }

    template <typename T>

    void wrapper(T &&args) {
        func(std::forward<T>(args));
    }

    int main() {

        int a = 10; 

        wrapper(a);

        wrapper(20);

        return 0;

    }

    如此,输出如下:

        func lvalue

        func rvalue

转载于:https://my.oschina.net/yepanl/blog/1929783

你可能感兴趣的文章
flask学习笔记之flask-migrate
查看>>
Swift练习题—基础控制流
查看>>
vue-router
查看>>
js基础归纳
查看>>
[译] 2019 年你应该要知道的 11 个 React UI 组件库
查看>>
技术专栏丨从原理到应用,Elasticsearch详解(上)
查看>>
JS学习笔记(一):数据类型判断
查看>>
Netty 源码解析系列-客户端连接接入及读I/O解析
查看>>
基于Spark的机器学习实践 (一) - 初识机器学习
查看>>
什么是散列表(Hash Table)
查看>>
iOS逆向(五)应用场景、基本思路、流程、
查看>>
GUI图形界面
查看>>
vue作用域插槽,你真的懂了吗?
查看>>
亮风台完成1.2亿元B+轮融资,加速AR平台商业化进程
查看>>
当提到“事件驱动”时,我们在说什么?
查看>>
PHP技术栈
查看>>
由“递归遍历二叉树”引发的思考
查看>>
HTTP长连接
查看>>
vue.js2.0 (简易)水果商城
查看>>
透视云原生热的背后
查看>>