Jan*_*tke 3 c++ language-lawyer perfect-forwarding c++23
auto()在 C++23 中,由于or ,完美转发纯右值变得更加容易auto{}。有了这个新工具,现在是否可以为具有以下要求的FORWARD(e)表达式构建表达式?e
FORWARD(e)与 具有相同的类型e,忽略引用限定符decltype(e)是左值/右值引用,则FORWARD(e)分别是左值/x值FORWARD(e)具有相同的值类别e我们已经可以进行不完美转发了std::forward:
#define FORWARD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
这会保留类型并适当地转换引用。但是,纯右值将转换为 xvalue,因为std::forward返回右值引用(即FORWARD(e)转换后是 xvalue)。
作为结果:
T x = T(); // copy elision because x is initialized to prvalue
T x = FORWARD(T()); // calls move constructor
Run Code Online (Sandbox Code Playgroud)
是否有可能在 C++ 中进行真正的完美转发,包括保留纯右值?
您基本上想要FORWARD(e)成为e,除非e碰巧命名了一个右值引用变量,在这种情况下您想要成为move(e)。
您可以简单地转换为 的类型decltype((e))(如果e是纯右值,则将被省略),除非e是右值引用变量,因为decltype((e))将是左值引用。
#include <type_traits>
template<typename IdType, typename ExprType>
using perfect_forward_cast = std::conditional_t<std::is_rvalue_reference_v<IdType>,
IdType,
ExprType
>;
#define FORWARD(...) ::perfect_forward_cast<decltype( __VA_ARGS__ ), decltype(( __VA_ARGS__ ))>( __VA_ARGS__ )
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/WYehMxzPb