Saturday, February 22, 2025

reference_wrapper

Overview
reference_wrapper is a class template that wraps a reference in a copyable, assignable object.

Details
reference_wrapper is a class template that wraps a reference in a copyable, assignable object.
It creates a wrapper around a reference to object or reference to function of type T. Instances of reference_wrapper are objects but they are implicitly convertible to T&, so that they can be used as arguments with the functions that take the underlying type by reference.
Helper functions ref and cref are often used to generate reference_wrapper objects.
reference_wrapper is used to pass objects by reference to bind, the constructor of thread, or the helper functions make_pair and make_tuple. It can also be used as a mechanism to store references inside standard containers (like vector) that cannot normally hold references.

The syntax is as shown below:
template <class T> class reference_wrapper;

constructors
Allocator based constructors are also available. 
NameDescription
reference_wrapper
(const reference_wrapper& x) 
Copy constructor.
reference_wrapper
 (T& ref)
The object stores a reference to ref.
Note that this constructor only accepts lvalues.
Example
int a(10),b(20),c(30);

// array of int&
reference_wrapper<int> refs[] = {a,b,c};
// vector of int&
vector<reference_wrapper<int>> vec {a,b,c};
//refs[0]=100 
//vec[0]=100
a=100;
The example 8 following lists the usage:

methods
NameDescription
reference_wrapper& operator=
(const reference_wrapper& rhs)
Copies the reference held by rhs, replacing the reference currently held in *this.
After the call, both rhs and *this refer to the same object or function.

Example
    int a,b;

    a=10; b=20;
    reference_wrapper<int> wrap1 (a);
    reference_wrapper<int> wrap2 (b);

    wrap1 = wrap2;
    ++wrap1; ++wrap2;

    //prints 10
    cout << "a: " << a << endl;
    //prints 22
    cout << "b: " << b << endl;


    a=10; b=20;
    int& ref1 (a);
    int& ref2 (b);

    ref1 = ref2;
    ++ref1; ++ref2;

    //prints 21
    cout << "a: " << a << endl;
    //prints 21
    cout << "b: " << b << endl;
T& get()
Returns a reference to the referred element.

Example
int a(10),b(20),c(30);

// array of int&
reference_wrapper<int> refs[] = {a,b,c};
// vector of int&
vector<reference_wrapper<int>> vec {a,b,c};
//a=100 
//vec[0]=100
refs[0].get()=100;
operator type&()
Returns a reference to the referred element.This returns the same as member get.

Example
int a(10),b(20),c(30);

// array of int&
reference_wrapper<int> refs[] = {a,b,c};

// vector of int&
vector<reference_wrapper<int>> vec {a,b,c};

//a=100 
//vec[0]=100
static_cast<int&>(refs[0])=100;
template<class... ArgTypes >
typename result_of<T&(ArgTypes&&...)>::type
operator() ( ArgTypes&&... args )
Accesses the referred element.
If type is a function or a function object type, it is called forwarding the arguments to the function.
If type is a pointer to a non-static member function, it is called using the first argument as the object on which the member is called, and the remaining arguments are forwarded as arguments for the function.
If type is a pointer to a non-static data member, it should be called with a single argument, and the function returns a reference to that member of its argument.

Example
void printnum(int n) {cout << n << endl;}
    auto  fp = ref(printnum);
   //prints 10
    fp(10);

ref
A helper function that constructs an object of the appropriate reference_wrapper type to hold a reference to elem.
Syntax
//creates a new reference_wrapper of type T&
template <class T> 
reference_wrapper<T> ref (T& elem);

//creates a copy of reference_wrapper from x  of type T&
template <class T> 
reference_wrapper<T> ref (reference_wrapper<T>& x);

Example
struct Msg
{
    char buf[50];
    void print(){cout << buf;};
} m;

    char  (Msg::*mbuf)[50] = &Msg::buf;
    auto pbuf = ref(mbuf);
    
    void (Msg::*mprint)() = &Msg::print;
    auto pprint = ref(mprint);

    char str[] = "hello, world!";
    auto len = char_traits<char>::length(str);
    //sets m.buf to "hello, world"
    char_traits<char>::copy(pbuf(&m),str,len);

    //calls m.print();
    //prints hello, world
    pprint(m);

cref
A helper function that constructs an object of the appropriate reference_wrapper type to hold a const reference to elem.
Syntax
//creates a new reference_wrapper of type const T&
template <class T> 
reference_wrapper<const T> ref (const T& elem);

//creates a copy of reference_wrapper from x of type const T& 
template <class T> 
reference_wrapper<const T> ref (reference_wrapper<T>& x);

Example
void f(int& n1, int& n2, const int& n3)
{
    //prints In function: 1 11 12
    cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << endl;
    ++n1; // increments the copy of n1 stored in the function object
    ++n2; // increments the main()'s n2
    // ++n3; // compile error
}
 
    int n1 = 1, n2 = 2, n3 = 3;
    function<void()> bound_f = bind(f, n1, ref(n2), cref(n3));
    n1 = 10;
    n2 = 11;
    n3 = 12;
    //prints Before function: 10 11 12
    cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << endl;
    bound_f();
    //prints After function: 10 12 12
    cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << endl;

The example 9 following lists the usage of ref and cref classes.

No comments:

Post a Comment