17

使用一个函数,可以编写:

template <class T> void f(T&& x) {myfunction(std::forward<T>(x));}

但是对于 lambda,我们没有T

auto f = [](auto&& x){myfunction(std::forward</*?*/>(x));}

如何在 lambda 中进行完美转发?decltype(x)可以作为 in 的类型工作吗std::forward

4

3 回答 3

25

转发绑定到转发引用的 lambda 参数的规范方法确实是decltype

auto f = [](auto&& x){
  myfunction(std::forward<decltype(x)>(x));
} //                      ^^^^^^^^^^^
于 2017-03-15T00:48:10.810 回答
6

我最喜欢的成语是:

auto f = [](auto&& x){myfunction(decltype(x)(x));}

我读为“x因为类型x被声明为”。

x要了解它是如何工作的,请检查当int&&. decltype(x)(x)is (int&&)(x),它产生对 的右值引用x。如果x是一个int&,那么我们得到(int&)(x)哪个是一个指向引用的 noop 。请记住,decltype(x)包括参考类别。

现在,对于auto&&参数,这更短但等效于:

auto f = [](auto&& x){myfunction(std::forward<decltype(x)>(x));}

替代方案。

对于auto参数:

auto f = [](auto x){myfunction(decltype(x)(x));}

它会产生一个额外的副本,而

auto f = [](auto x){myfunction(std::forward<decltype(x)>(x));}

而是从x.

虽然我通常认为 C 风格的强制转换过于危险,但最坏的情况是可以制作一个类型正确的if is not a variabledecltype(x)(x)副本。为了简洁起见,有话要说。xxauto&&

于 2017-03-15T01:34:34.890 回答
6

使用 C++20,您现在可以为 lambda 指定模板参数列表。以下内容直接取自https://en.cppreference.com/w/cpp/language/lambda

auto f = []<typename ...Ts>(Ts&& ...ts) {
    return foo(std::forward<Ts>(ts)...);
};
于 2021-01-03T15:06:30.303 回答