To set a std::function variable to a lambda function with default argument I can use auto
as in:
auto foo = [](int x = 10){cout << x << endl;};
foo();
This will print 10.
But I want the foo variable to reside in a struct. In a struct I cannot use auto
.
struct Bar
{
auto foo = [](int x = 10}(cout << x << endl}; //error: non-static data member declared ‘auto’
};
Bar bar;
bar.foo();
Replacing auto
with std::function
struct Bar
{
std::function<void(int x = 10)> foo = [](int x = 10}(cout << x << endl}; //error: default arguments are only permitted for function parameters
};
Bar bar;
bar.foo();
or
struct Bar
{
std::function<void(int)> foo = [](int x = 10}(cout << x << endl};
};
Bar bar;
bar.foo(); //error: no match for call to ‘(std::function<void(int)>) ()’
Without the struct and replacing auto
for std::function:
std::function<void(int x)> foo = [](int x = 10){cout << x << endl;};
foo(); //error: no match for call to ‘(std::function<void(int)>) ()’
So how should I declare foo?
Don't know if that will help you, but you can store a lambda in a templated struct.
The signature in
std::function
is based on how you plan to call it and not on how you construct/assign it. Since you want to call it two different ways, you'll need to store to differentstd::function
objects, as in:Alternatively, you can do the type erasure yourself (what
std::function
does behind the scenes) to only store the lambda once, as in:One way you could solve this would be to wrap your
std::function
in a functor object which implements the default arguments for you:In C++20 you will be able to do this:
Live on Godbolt
It does look a bit strange, but it works just fine.
What makes this possible is the ability to use lambdas in unevaluated contexts and default construct stateless lambdas.