Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A forwarding reference (historically referred to as a “universal reference”) is an rvalue reference to a cv-unqualified template type parameter (T&&) or an auto&& declaration that preserves the value category (lvalue or rvalue) and cv-qualifiers (const/volatile) of the argument bound to it. Because it relies on template argument deduction, a forwarding reference can bind to any value category: mutable lvalues, const lvalues, mutable rvalues, and const rvalues.

Syntax and Context

A forwarding reference only exists in contexts where type deduction takes place. There are two primary forms:
// 1. Template type parameter deduction
template <typename T>
void process(T&& param); 

// 2. auto type deduction
auto&& var = some_expression(); 

Mechanics: Type Deduction and Substitution

The behavior of a forwarding reference is governed by C++ rules for Special Template Argument Deduction, Standard Substitution, and Reference Collapsing. When a function template parameter is declared as T&&, the compiler applies special deduction rules based on the value category of the passed argument:
  • If the argument is an lvalue of type A, the template parameter T is deduced as an lvalue reference: A&.
  • If the argument is an rvalue of type A, the template parameter T is deduced as the non-reference type: A.
During template instantiation, substituting T into the signature T&& yields the final parameter type. Reference collapsing strictly occurs only when substitution creates a reference to a reference:
Value Category PassedDeduced TSubstituted SignatureMechanismFinal Parameter Type
LvalueA&A& &&Reference CollapsingA& (Lvalue reference)
RvalueAA &&Standard SubstitutionA&& (Rvalue reference)
(Note: The complete reference collapsing rule set dictates that & &, & &&, and && & collapse to &, while && && collapses to &&.)

Internal Value Category and std::forward

A crucial C++ language rule dictates that named variables are always lvalues, regardless of their declared type. Inside the function body, the forwarding reference parameter (e.g., param) is an lvalue, even if it originally bound to an rvalue and its deduced type is A&&. Because param is an lvalue, passing it to another function will always pass it as an lvalue. To preserve and forward the original value category of the argument, developers must use std::forward<T>(param). std::forward is a conditional cast: it casts the parameter back to an rvalue if and only if T was deduced as a non-reference type (which indicates the original argument was an rvalue).
#include <utility>

template <typename T>
void process(T&& param) {
    // 'param' has a name, so it is an lvalue here.
    // Passing 'param' directly to another function passes an lvalue.
    
    // std::forward conditionally casts 'param' to an rvalue 
    // ONLY if the original argument was an rvalue.
    target_function(std::forward<T>(param)); 
}

Strict Structural Requirements

For T&& to act as a forwarding reference, it must be exactly T&&. The addition of cv-qualifiers or compound type structures disables the special deduction rules, turning the parameter into a standard rvalue reference.
template <typename T>
void func1(const T&& param); 
// NOT a forwarding reference. It is an rvalue reference to const T.

template <typename T>
void func2(std::vector<T>&& param); 
// NOT a forwarding reference. It is an rvalue reference to a vector.

template <typename T>
class Wrapper {
    void method(T&& param); 
    // NOT a forwarding reference. 'T' is deduced when the class is 
    // instantiated, so no deduction occurs at the method call site.
};
To achieve a forwarding reference in a class method, the method itself must be templated independently of the class:
template <typename T>
class Wrapper {
    template <typename U>
    void method(U&& param); // This IS a forwarding reference.
};
Master C++ with Deep Grasping Methodology!Learn More