zoukankan      html  css  js  c++  java
  • [C++11]_[0基础]_[左值引用声明和右值引用声明]

    场景:

    1. 在 remove_reference 结构体中能看到右值引用的身影 &&, 那么这里的右值引用究竟有什么用呢?

    2. 常常也发现int& 和int&& 这两种相似的应用类型,第一种是左值引用声明,另外一种是右值引用声明.
    3. 下面的样例直接參考的 cppreference,已经写的非常完整了,不是必需又一次写.

    參考:

    1.Reference declaration
    2.Rvalue Reference Declarator: &&
    3.Lvalue Reference Declarator: &

    语法

    左值引用声明: & attr(optional) declarator (1)
    右值引用声明: && attr(optional) declarator (2) (since C++11)

    左值引用声明 &

    –1. 左值引用能够理解为对象的别名, 左值引用必须被初始化并且不能被又一次赋值.

    #include <iostream>
    #include <string>
    
    int main()
    {
        std::string s = "Ex";
        std::string& r1 = s;
        const std::string& r2 = s;
    
        r1 += "ample";           // modifies s
    //  r2 += "!";               // error: cannot modify through reference to const
        std::cout << r2 << '
    '; // prints s, which now holds "Example"
    }

    –2. 在调用函数时,能够被用来作为引用參数.

    #include <iostream>
    #include <string>
    
    void double_string(std::string& s)
    {
        s += s; // 's' is the same object as main()'s 'str'
    }
    
    int main()
    {
        std::string str = "Test";
        double_string(str);
        std::cout << str << '
    ';
    }

    –3. 当一个函数的返回值是左值时, 这个函数的调用的表达式能够被觉得是一个左值表达式.

    
    #include <iostream>
    #include <string>
    
    char& char_number(std::string& s, std::size_t n)
    {
        return s.at(n); // string::at() returns a reference to char
    }
    
    int main()
    {
        std::string str = "Test";
        char_number(str, 1) = 'a'; // the function call is lvalue, can be assigned to
        std::cout << str << '
    ';
    }

    右值引用声明 &&

    –1. 右值引用声明能够差别一个左值和右值.
    –2. 右值引用直至Move语义的实现, 它能够把暂时对象(一般不能引用)的资源移动到其它地方去.

    –3. 右值引用也能够用来扩展暂时对象的生命周期,

    #include <iostream>
    #include <string>
    
    int main()
    {
        std::string s1 = "Test";
    //  std::string&& r1 = s1;           // error: can't bind to lvalue
    
        const std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime
    //  r2 += "Test";                    // error: can't modify through reference to const
    
        std::string&& r3 = s1 + s1;      // okay: rvalue reference extends lifetime
        r3 += "Test";                    // okay: can modify through reference to non-const
        std::cout << r3 << '
    ';
    }

    –4. 假设函数有左值和右值引用的重载,调用时会匹配调用, 传左值调用左值重载, 右值调用右值重载. 这样就能够支持Move Constructor 和 Move Assignment 的实现.

    #include <iostream>
    #include <utility>
    
    void f(int& x)
    {
        std::cout << "lvalue reference overload f(" << x << ")
    ";
    }
    
    void f(const int& x)
    {
        std::cout << "lvalue reference to const overload f(" << x << ")
    ";
    }
    
    void f(int&& x)
    {
        std::cout << "rvalue reference overload f(" << x << ")
    ";
    }
    
    int main()
    {
        int i = 1;
        const int ci = 2;
        f(i);  // calls f(int&)
        f(ci); // calls f(const int&)
        f(3);  // calls f(int&&)
               // would call f(const int&) if f(int&&) overload wasn't provided
        f(std::move(i)); // calls f(int&&)
    }
  • 相关阅读:
    centos7系统中忘记了root管理员账号密码的解决方式
    【python之路48】生成器表达式、推导式
    小米集团信息化中台战略
    分时函数
    函数节流
    JS浮点计算问题
    要转型做前端开发了
    优秀的开发人员和测试人员应有的态度
    C#数组的笔记
    LINQ不包含列表
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7232036.html
Copyright © 2011-2022 走看看