When I try to compile this:
#include <functional>
void f(std::function<void()> f)
{
}
void g()
{
f([](auto&&...){});
}
on gcc 7.3, I get the following error:
[x86-64 gcc 7.3 #1] error: could not convert '
<lambda closure object>g()::<lambda(auto:1&&, ...)>{}
' from 'g()::<lambda(auto:1&&, ...)>
' to 'std::function<void()>
'
Can someone explain why this is invalid c++? Or should I submit a bug report? (MSVC 14 accepts and compiles it to what I expect.)
The auto keyword in C++ automatically detects and assigns a data type to the variable with which it is used. The compiler analyses the variable's data type by looking at its initialization. It is necessary to initialize the variable when declaring it using the auto keyword.
Permalink. All the alternatives to passing a lambda by value actually capture a lambda's address, be it by const l-value reference, by non-const l-value reference, by universal reference, or by pointer.
However, a capture-less lambda has an additional function-pointer conversion operator declared in it. It is that function-pointer conversion operator that makes a capture-less lambda convertible to a function pointer.
This is a gcc bug. It interprets your lambda as follow:
[](auto&&, ...){}
So there's one argument, followed by C variadic.
If you add a name to your parameter pack, then it works as intended:
[](auto&&... pack){}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With