在lambda中完美转发?

时间:2017-03-15 00:43:01

标签: c++ lambda c++14 decltype forwarding-reference

使用函数,可以写:

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)中的std::forward类型是否有效?

3 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:4)

我最喜欢的成语是:

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

我将其视为&#34; x,因为类型x被声明为&#34;。

要了解其工作原理,请检查xint&&时会发生什么。 decltype(x)(x)(int&&)(x),它会生成对x的右值引用。如果xint&,那么我们会得到(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风格的演员表视为过于危险,但如果decltype(x)(x)不是x,则x最不能制作auto&&的类型正确副本变量。为了简洁起见,还有一些事情可以说。

答案 2 :(得分:3)

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

auto f = []<typename ...Ts>(Ts&& ...ts) {
    return foo(std::forward<Ts>(ts)...);
};