Reputation:
If I want to make a lambda of type std::function<void(const Foo&)>
.
Why is it legal to drop the reference and the constness of the argument?
This is valid:
std::function<void(const Foo&)> f = [](Foo) {
// ...
};
Upvotes: 4
Views: 121
Reputation: 36802
std::function
works as long as the called function has parameters and return type that allow std::function::operator()
to pass along its arguments. std::function
isn't the lambda expression's type, it is a container that can store a lambda as well as other callables. Your original example works for the same reason this works:
void take_value(Foo) { }
void take_reference(const Foo& foo) {
// fine, makes a copy while calling
take_value(foo);
}
To illustrate the compatibility requirements of std::function
, the following all work:
#include <functional>
int main() {
// fine, can pass an int to function taking double
std::function<void(int)> f1 = [] (double) { };
// fine, just ignore the return
std::function<void()> f2 = [] {return 1;};
// fine, can return the int as a double
std::function<double()> f3 = [] { return 1;};
}
Upvotes: 1
Reputation: 238321
If I want to make a lambda of type
std::function<void(const Foo&)>
That type is not a lambda, so you cannot have a lambda of that type. I suppose that you mean, that you want to store a lambda in a function wrapper of that type.
Why is it legal to drop the reference and the constness of the argument?
Because a Foo
(the argument of the lambda) can be initialised from a const Foo&
(the argument of the function wrapper). You can do this without a lambda as well:
const Foo& ref{some_value};
Foo f {ref};
Upvotes: 8