Stdreference Wrapper In C++

An assignable object or reference to a function of type T can be wrapped in a copy constructible by using the class template std::referencewrapper . It is possible to copy or store instances of std::referencewrapper in containers, but they are implicitly convertible to "T&" so that they can be used as arguments in functions that accept the underlying type by reference.

When we cannot use raw references directly, the std::reference_wrapper function stores references in containers or passes them around as function arguments.

The std::reference_wrapper is frequently used in reference-based algorithms where references must be handled polymorphically, passing references to functions that take arguments by value, and storing references in containers.

Syntax:

It has the following syntax:

Example

template <class T> class reference_wrapper;
template parameter(T): type of the referred element and this can be  either function or object.

Example 1:

Let us take an example to illustrate the std::reference_wrapper in C++.

Example

#include <iostream>
#include <functional>
#include <vector>

void modify(int& x) {
    x *= 2;
}

int main() {
    int value = 10;
    std::vector<std::reference_wrapper<int>> vec;
    
    // Store references in the vector using std::reference_wrapper
    vec.push_back(std::ref(value));
    vec.push_back(value); // Alternatively, you can use std::ref() directly
    
    // Modify the original value through the reference wrappers
    for(auto& ref : vec) {
        modify(ref);
    }
    
    // Original value has been modified
    std::cout << "Modified value: " << value << std::endl;
    
    return 0;
}

Output:

Output

Modified value: 40

Explanation:

In this example, a function modify receives references that are passed to it for modification via std::referencewrapper , which enables references to be stored in a std::vector. Overall, the std::referencewrapper offers a versatile and secure method of working with references in situations where it is neither desirable nor practical to use references directly.

Example 2:

Let us take another example to illustrate the std::reference_wrapper in C++.

Example

#include <iostream>
#include <functional>
#include <vector>

// Function to double the value of the referenced integer
void doubleValue(int& x) {
    x *= 2;
}

int main() {
    // Create a vector to store references to integers
    std::vector<std::reference_wrapper<int>> intRefs;

    // Some integer values
    int a = 5;
    int b = 10;
    int c = 15;

    // Store references to these integers in the vector
    intRefs.push_back(std::ref(a));
    intRefs.push_back(std::ref(b));
    intRefs.push_back(std::ref(c));

    // Double the values of all integers using std::reference_wrapper
    for (int& ref : intRefs) {
        doubleValue(ref);
    }

    // Print the modified values
    std::cout << "Modified values:" << std::endl;
    std::cout << "a: " << a << std::endl;
    std::cout << "b: " << b << std::endl;
    std::cout << "c: " << c << std::endl;

    return 0;
}

Output:

Output

Modified values:
a: 10
b: 20
c: 30

Explanation:

  • In this example, the references to integers are kept in a vector called intRefs .
  • We define a, b, and c, three integer variables.
  • Using the std::ref function, references to these integers are kept in the vector.
  • After that, we define a function called doubleValue to double the value of the referenced integer.
  • By iterating through the reference vector and passing each reference to doubleValue, we are able to double the value of each integer that is referenced.
  • Ultimately, we output the updated integer values.
  • Example 3:

Let us take another example to illustrate the std::reference_wrapper in C++.

Example

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

// Function to print the value of the referenced integer
void printValue(int& x) {
    std::cout << x << " ";
}

int main() {
    // Create a vector of integers
    std::vector<int> numbers = {4, 7, 2, 9, 5};

    // Create a vector to store references to integers
    std::vector<std::reference_wrapper<int>> numberRefs;

    // Populate the vector of references
    for (int& num : numbers) {
        numberRefs.push_back(std::ref(num));
    }

    // Print original values
    std::cout << "Original values: ";
    std::for_each(numbers.begin(), numbers.end(), printValue);
    std::cout << std::endl;

    // Increment each value using std::reference_wrapper and std::for_each algorithm
    std::for_each(numberRefs.begin(), numberRefs.end(), [](int& x) { x++; });

    // Print modified values
    std::cout << "Modified values: ";
    std::for_each(numbers.begin(), numbers.end(), printValue);
    std::cout << std::endl;

    return 0;
}

Output:

Output

Original values: 4 7 2 9 5 
Modified values: 5 8 3 10 6

Conclusion:

In conclusion, when using references directly isn't possible or desired, like when storing references in containers or passing them to algorithms that need copyable elements, C++'s std::referencewrapper offers a useful and secure way to work with references. The std::referencewrapper function is a wrapper that encapsulates references inside an object-like structure. It allows references to be treated polymorphically and used in situations where using raw references would be inappropriate, like in standard containers like vectors or maps. Additionally, std::referencewrapper preserves reference semantics, guaranteeing that operations carried out on the wrapper have an impact on the original referenced object. Because of its adaptability and security, std::referencewrapper is a useful tool for programmers who want to take advantage of references in a variety of programming scenarios while still abiding by the limitations imposed by specific language constructs or library interfaces.

Input Required

This code uses input(). Please provide values below: