右值引用

发布时间:2019-06-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了右值引用脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

右值引用


1. 什么是左值和右值

几种区分方法:

  • 左值就是即能出现在等号左边也能出现在等号右变的变量(表达式), 右值就只能出现在等号的右边
  • 能取地址的就是左值,不能取地址的就是右值
int i, j, k;
i = 1; // i是左值, 1是右值
i = j; // i, j 都是左值 1 = i; // 错误, 1是右值

2. 什么是左值引用和右值引用

如果左值同时又有&标识符,就被称为左值引用

int i = 0;
int& j = i; // j为左值引用
int& k = 1; // 错误,右值是不可修改的,所以k被绑定到1是语法错误
const int& k2 = 1 // 正确,const 左值引用不能被修改

右值通过&&符号表明它是一个右值引用,只能绑定到右值上

int i = 0;
int&& j = i; // 错误,右值引用不能绑定到左值上
int&& k = 1; // 正确
int&& k2 = i + 42; // 正确, i + 42是右值
int& k3 = i + 42; // 错误

3.右值引用它要解决什么问题,怎么使用

c++11引入右值引用主要解决两个问题:

1.对需要拷贝的临时对象(右值)进行移动操作,提升效率

c++11以前,因为想避免深拷贝的性能损失,我们把本应该写成

vector<int> GetResource(int args); // (1)

写成了

void GetResouce(int args, vector<int>* output); // (2)

在c++中,我们可以大胆的写成(1)这种形式,如果返回的是栈对象,就会优先调用移动构造函数,而不是拷贝构造函数
在我们写函数声明的时候,只有当:

@H_406_177@
  • 函数内需要copy参数时
  • 需要将参数保存到栈外内存时
  • 我们可以把参数声明为右值引用,比如标准库里的vertorpush_back

    void push_back(const T& v);
    void push_back(T&& v);

    如果只满足第一个条件,我们可以使用

    void Func(const T& v)
    {
        // 这里直接调用一次copy构造函数
        local l = v;
    }

    2.在模板函数中按参数的实际类型进行转发

    void Fun(const int&)
    {
        std::cout << "lvalue" << std::endl;
    }
    
    void Fun(int&& i)
    {
        std::cout << "rvalue" << std::endl;
    }
    
    template <typename T>
    void ForwardValue(T&& v)
    {
        // 使用forward把值的类型原样转发给Fun
        Fun(std::forward<T>(v));
    }
    
    int main()
    {
        ForwardValue(1);
        int a = 1;
        ForwardValue(a);
        return 0;
    }

    脚本宝典总结

    以上是脚本宝典为你收集整理的右值引用全部内容,希望文章能够帮你解决右值引用所遇到的问题。

    如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。