user7475082
user7475082

Reputation:

Const argument in lambdas

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

Answers (2)

Ryan Haining
Ryan Haining

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

eerorika
eerorika

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

Related Questions