C++ 在模板参数和 lambda 的“auto”参数之间转发引用方面的差异

Per*_*-lk 1 c++ reference rvalue-reference forwarding-reference c++17

比较以下两种情况:

template<class... Args>
void f1(Args&&... args) { do_smth(std::forward<Args>(args)...); }

auto f2 = [](auto&&... args) { do_smth(std::forward<decltype(args)>(args)...); };
Run Code Online (Sandbox Code Playgroud)

std::forward传递或不传递的类型是否有任何差异?

根据我的理解,当您使用 , 指定转发引用时T&&,&&并不与传递的参数“匹配”,而是一种将“原始引用”信息“存储”到T(T将是&, const &,&&或const &&根据值类别传递的参数),然后将此类“原始引用”信息结合起来,使用通常的规则等&&计算最终的引用类型。& + && = &

我不知道的是,是否decltype(args)会解析为此类计算“之前”或“之后”的类型,或者结果类型是否与“原始引用”不同,因此指定的类型是否有任何差异std::forward在f1和f2.

注意:我不能使用 C++20,并且模板 lambda 不在问题范围内。

Hol*_*Cat 5

T根据值类别将是&, const &,&&或const &&

T永远不会被推导为右值引用。但它可以被推断为非引用(对于右值参数),可能是 const。

我不知道是否decltype(args)会解析为此类计算“之前”或“之后”的类型

当然是之后。

这意味着当(虚数)T是非引用时,而是decltype接收T &&。但std::forward对待T和T &&方式是一样的,所以你的用法是可以的。

此外,您甚至不需要forward并且只需使用decltype(args)(args)(强制转换为decltyped 类型),尽管有些人更喜欢为了清楚起见而拼写出多余的内容std::forward。