Perfect forwarding in a lambda?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 05:53:31
Kerrek SB

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));
} //                      ^^^^^^^^^^^

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.

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