How Forward reference used in C++ 11

In this post, we are going to understand How Forward reference used in C++ 11 with examples

What is Forward reference in C++ 11


This concept of Forwarding references is new in C++ 11. The concept was first given a name as a universal reference by Scott Meyers, then the C++ Standard committee changed the name to Forwarding references. But by concept both are one and the same thing.

Syntax of Forward references is:

T&&
or
auto&&


But remember that we already have rvalue references with the same syntax. Then what is the difference???, Let us understand this with an example below:

Difference between universal and Forwarding references


So if you see the examples above you can see a difference that when we use template parameter type or auto, this becomes forward reference. When we know the parameter type upfront as in the above example we have int&& this is an rvalue reference.

It means the forward reference is just the generalization of rvalue reference.

int&& // this is rvalue refernce
T&&   // this is forward reference
auto&& // this is forward reference

Now, let us understand this in more detail with some examples. We have two functions below.The addition() and maths() . Both the functions have one argument with &&.

Addition():

  • The addition function is taking an argument of type rvalue reference to a non-const as input.
  • The argument x has to be always rvalue.
  • The argument x is capturing temporary values.

maths():

  • maths() is taking an argument that can be an lvalue or rvalue reference to const, volatile, or both.
  • The argument T can be of any type.
  • The argument T is forwarding the arguments.

Example

void addition( int&& x );
template
void maths( T&& num );

In the below example we are calling the functions Addition() and maths().See the calling of these functions:

Program Example

//var is an lvalue of type int

int var = 20;

// This is OK. addition(int&&)

addition(10);

// addition(int&) This is not OK , because var should be rvalue to be accepted by addition.

addition(var);


// This is OK

maths(10); 

// This is OK because var can be rvalue or lvalue to be accepted by maths

maths(var);

Forwarding references allow a reference to binding to either an lvalue or rvalue depending on the type.

Program Example

auto&& num = var; // num is an lvalue of type int& , because var is int

auto&& num = 10; // num is an lvalue of type int&& , because 10 is temporary value (rvalue)

T&& num = var; // num is an lvalue of type int& , because var is int

T&& num = 10; // num is an lvalue of type int&& , because 10 is temporary value (rvalue)

Forward references enable perfect forwarding which means the ability to pass arguments by maintaining their value category.