Open In App

std::forward in C++

Last Updated : 26 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In C++, std::forward() is a template function used for achieving perfect forwarding of arguments to functions so that it's lvalue or rvalue is preserved. It basically forwards the argument while preserving the value type of it.

std::forward() was introduced in C++ 11 as the part of <utility> header file.

Syntax

std::forward<T> (arg)

where,

  • arg: Argument to be forwarded.

Example of std::forward()

C++
// C++ program to illustrate the use of
// std::forward() function
#include <iostream>
#include <utility>
using namespace std;

// Function that takes lvalue reference
void UtiltyFun(int& i) {
    cout << "Process lvalue: " << i << endl;
}

// Overload of above function but it takes rvalue
// reference
void UtiltyFun(int&& i) {
    cout << "Process rvlaue: " << i << endl;
}

// Template function for forwarding arguments
// to utlityFun() 
template <typename T>
void Fun(T&& arg) {
    UtiltyFun(forward<T>(arg));
}

int main() {
    int x = 10;
  	
  	// Passing lvalue
    Fun(x);
  
  	// Passing rvalue
    Fun(move(x)); 
}

Output
Process lvalue: 10
Process rvlaue: 10

Explanation:

Here, in function fun(), T&& is called as universal reference which means it can hold both type (lvalue and rvalue). By using std::forward(), it will check what type is coming in arg. Based on whether it is lvalue or rvalue, it will call the correct overloaded version of the utilityFun().

If we don't use std::forward, it will every time call lvalue version of utilityFun(int &i), as compiler won't check the type of arg and assumed that it is lvalue only, which we will see in below example.

Above Example Without std::forward

C++
// C++ Program to illustrate what will happen if we
// don't use std::forward for argument passing
#include <iostream>
#include <utility>
using namespace std;

// Function with lvalue reference parameter
void utiltyFun(int& i) {
    cout << "Process lvalue: " << i << endl;
}

// Overload of above function with rvalue
// reference arameter
void utiltyFun(int&& i) {
    cout << "Process rvlaue: " << i << endl;
}

// Function that forwards argument
template <typename T>
void fun(T&& arg) {
    utiltyFun(arg);
}


int main() {
    int x = 10;
  
  	// Passing lvalue
    fun(x); 
  
  	// Passing rvalue
    fun(move(x)); 
}

Output
Process lvalue: 10
Process lvalue: 10

Things to Remember

In the above program,

  • std::move() function will cast its arguments unconditionally, means either if we pass lvalue or rvalue it will cast it to rvalue, it doesn't move anything.
  • std::forward will cast its argument to rvalue only if argument coming is rvalue.
  • std::move and std::forward won't do anything in runtime.

Next Article
Article Tags :
Practice Tags :

Similar Reads