C++ Difference between std::ref(T) and T&?

后端 未结 3 1271
既然无缘
既然无缘 2021-01-29 22:30

I have some questions regarding this program:

#include 
#include 
#include 
using namespace std;
template &l         


        
3条回答
  •  有刺的猬
    2021-01-29 23:19

    Well ref constructs an object of the appropriate reference_wrapper type to hold a reference to an object. Which means when you apply:

    auto r = ref(x);
    

    This returns a reference_wrapper and not a direct reference to x (ie T&). This reference_wrapper (ie r) instead holds T&.

    A reference_wrapper is very useful when you want to emulate a reference of an object which can be copied (it is both copy-constructible and copy-assignable).

    In C++, once you create a reference (say y) to an object (say x), then y and x share the same base address. Furthermore, y cannot refer to any other object. Also you cannot create an array of references ie code like this will throw an error:

    #include 
    using namespace std;
    
    int main()
    {
        int x=5, y=7, z=8;
        int& arr[] {x,y,z};    // error: declaration of 'arr' as array of references
        return 0;
    }
    

    However this is legal:

    #include 
    #include   // for reference_wrapper
    using namespace std;
    
    int main()
    {
        int x=5, y=7, z=8;
        reference_wrapper arr[] {x,y,z};
        for (auto a: arr)
            cout << a << " ";
        return 0;
    }
    /* OUTPUT:
    5 7 8
    */
    

    Talking about your problem with cout << is_same::value;, the solution is:

    cout << is_same::value;  // will yield true
    

    Let me show you a program:

    #include 
    #include 
    #include 
    using namespace std;
    
    int main()
    {
        cout << boolalpha;
        int x=5, y=7;
        reference_wrapper r=x;   // or auto r = ref(x);
        cout << is_same::value << "\n";
        cout << (&x==&r.get()) << "\n";
        r=y;
        cout << (&y==&r.get()) << "\n";
        r.get()=70;
        cout << y;
        return 0;
    }
    /* Ouput:
    true
    true
    true
    70
    */
    

    See here we get to know three things:

    1. A reference_wrapper object (here r) can be used to create an array of references which was not possible with T&.

    2. r actually acts like a real reference (see how r.get()=70 changed the value of y).

    3. r is not same as T& but r.get() is. This means that r holds T& ie as its name suggests is a wrapper around a reference T&.

    I hope this answer is more than enough to explain your doubts.

提交回复
热议问题