In C++23, it became easier to perfectly forward prvalues thanks to auto()
or auto{}
. With this new tool, is it now possible to form a FORWARD(e)
expression for an expression e
with the following requirements?
FORWARD(e)
has the same type ase
, disregarding reference qualifiers- if
decltype(e)
is an lvalue/rvalue reference, thenFORWARD(e)
is an lvalue/xvalue respectively - otherwise,
FORWARD(e)
has the same value category ase
- no additional copying or moving may take place
We can do imperfect forwarding with std::forward
already:
#define FORWARD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
This preserves the type and converts references appropriately.
However, a prvalue will be turned into an xvalue, because std::forward
returns an rvalue reference (i.e. FORWARD(e)
is an xvalue after conversions).
As a consequence:
T x = T(); // copy elision because x is initialized to prvalue
T x = FORWARD(T()); // calls move constructor
Is it possible to do true perfect forwarding in C++, including preservation of prvalues?