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

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Question

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

MatrixMathMax
Linear Algebra Dev
MEMBER
Rep: 279
Join Date: May 2024
Posts: 6
Thanks: 85
2y ago · May 13, 2024 9:40 AM
#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?
MatrixMathMax · Linear Algebra Dev
Matrix decomposition (LU/QR/Cholesky), singular value decompositi...
The following users thanked MatrixMathMax for this post:
FlatMapFan
Cache-Friendly Containers
MEMBER
Rep: 353
Join Date: Oct 2023
Posts: 6
Thanks: 97
2y ago · May 13, 2024 11:10 AM
#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.
FlatMapFan · Cache-Friendly Containers
Sorted vector flat_map vs red-black tree std::map benchmarks in h...
TemplateTitan
Template Metaprogramming
MEMBER
Rep: 80
Join Date: Apr 2023
Posts: 6
Thanks: 49
2y ago · May 13, 2024 12:10 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)!
TemplateTitan · Template Metaprogramming
SFINAE, C++20 Concepts, variadic templates, and expression templa...