Perfect forwarding in a lambda?

做~自己de王妃 提交于 2019-12-07 00:48:37

问题


With a function, one can write:

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

but with a lambda, we don't have T:

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

How to do perfect-forwarding in a lambda? Does decltype(x) work as the type in std::forward?


回答1:


The canonical way to forward a lambda argument that was bound to a forwarding reference is indeed with decltype:

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



回答2:


My favorite idiom for this is:

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

which I read as "x as the type x was declared as".

To see how this works, examine what happens when x is an int&&. decltype(x)(x) is (int&&)(x), which produces an rvalue reference to x. If x is an int&, then we get (int&)(x) which is a noop cast to a reference. Remember, decltype(x) includes the reference category.

Now, for auto&& parameters this is shorter but equivalent to:

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

the alternative.

For auto parameters:

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

it induces an extra copy, while

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

instead moves-from x.

While I usually treat C-style casts as being too dangerous, decltype(x)(x) can at worst make a type-correct copy of x if x is not an auto&& variable. And there is something to be said for the brevity of it.



来源:https://stackoverflow.com/questions/42799208/perfect-forwarding-in-a-lambda

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!