41

C++14 supports generic lambdas. However, the following code is rejected by clang 3.4.

#include <utility>

void f(int);
void f(int&);

int main()
{
    [](auto&& v) { f(std::forward<auto>(v)); }(8); // error
}

How to perfectly forward auto&& in a generic lambda?

xmllmx
  • 39,765
  • 26
  • 162
  • 323

1 Answers1

48

auto is not a type so I’m not surprised this doesn’t work. But can’t you use decltype?

[](auto&& v) { f(std::forward<decltype(v)>(v)); }(8);

Scott Meyers has more details.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 5
    DRY -- `#define FORWARD(x) std::forward(x)` -- ick. – Yakk - Adam Nevraumont Jul 02 '14 at 17:53
  • 13
    @Yakk But also AGUOM: Avoid Gratuitous Use Of Macros. ;-) – Konrad Rudolph Jul 02 '14 at 18:49
  • 4
    If something requires a macro to DRY, figure out how to improve the language! – Yakk - Adam Nevraumont Jul 02 '14 at 18:54
  • 1
    Without rehashing a general discussion about macros, is there anything broken about this particular macro? It won't work with parameter packs (`auto ...`) but otherwise it is correct isn't it? – Aaron McDaid Aug 31 '14 at 12:44
  • 6
    @Aaron The name is wrong: every long-lived macro should be namespaced to avoid name clashes (i.e. be called something like `MY_LIBRARY_NAME_FORWARD`), which of course greatly decreases its readability. More fundamentally, the macro simply isn’t necessary. I agree with Yakk about “DRY” but the thing being repeated here is a single, simple identifier rather than a complex expression. – Konrad Rudolph Sep 02 '14 at 12:01
  • @AaronMcDaid are you sure it doesn't work with parameter packs, as `[](auto&&... obj){do_something(FORWARD(obj)...);}`? – bit2shift Apr 22 '17 at 14:30
  • I'm not sure, @bit2shift. I'm not entirely sure why I wrote that :) . In hindsight, the macro should work fine with expansion. It's likely that I simply didn't understand pack expansion very well when I wrote that first – Aaron McDaid May 04 '17 at 09:49
  • @KonradRudolph Don’t you also in general want to `std::decay` the `decltype` here, that is `std::forward>(v)` ? – HyperBoar Feb 03 '21 at 22:32