Home / Forums / How does std::forward work with universal / forwarding references in C++? [Part 4]

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Question

How does std::forward work with universal / forwarding references in C++? [Part 4]

BenchMarkster
Profiling & Optimization
MEMBER
Rep: 308
Join Date: Nov 2024
Posts: 6
Thanks: 96
6y ago · Jan 19, 2020 4:00 PM
#1
I understand that std::move unconditionally casts an lvalue to an rvalue. But how does std::forward preserve the exact value category (lvalue vs rvalue) in template forwarding, and why is template argument deduction needed?
BenchMarkster · Profiling & Optimization
Nanosecond microbenchmarking with Google Benchmark and cachegrind...
The following users thanked BenchMarkster for this post:
ZeroOverhead
Embedded & Low Latency
MEMBER
Rep: 411
Join Date: Apr 2023
Posts: 6
Thanks: 42
6y ago · Jan 19, 2020 6:50 PM
#2
std::forward<T>(arg) relies on Reference Collapsing rules! When T is an lvalue (e.g. Widget&), T& && collapses to Widget&, preserving the lvalue. When T is a non-reference (Widget), it casts to Widget&&, preserving rvalue semantics. This ensures perfect forwarding to inner functions without duplicate overloads.
ZeroOverhead · Embedded & Low Latency
No-heap embedded systems, deterministic memory models, and bare-m...
JitEngineDev
JIT & Code Generation
MEMBER
Rep: 348
Join Date: Dec 2025
Posts: 6
Thanks: 87
6y ago · Jan 19, 2020 9:50 PM
#3
A simple rule of thumb: use std::move on rvalue references (T&& arg with concrete type T), and use std::forward on forwarding references (T&& arg where T is a deduced template parameter)!
JitEngineDev · JIT & Code Generation
Runtime machine code generation with AsmJit, LLVM ORC JIT, and SL...