3
votes

Question about implicit lambda conversions. I have this type:

class A {
 public:
  A(std::function<void(std::string)> func) {
    ....
  }
};

Which I believe has a valid copy constructor.

As I would like to do the following

A a = [](std::string param) { ... };

Or

void MyFunc(A a) { ... }  // definition

MyFunc([](std::string param) { ... });  // call

Yet both these yield compile error:

note: candidate constructor not viable: no known conversion from '(lambda at ....)' to 'std::function' for 1st argument

Why is this? Or should this be possible?

1
Dummying up some simple code and trying it with gcc 8.1.1 shows that constructing the object using uniform initialization syntax works fine. I won't bother writing up an answer because it's highly likely that your real code does not resemble these isolated code snippets which only vaguely resemble C++ code, and because of that your real issue might be somewhere else. You need to take a tour of stackoverflow.com, go to the help center, read the instructions for creating a minimal reproducible example, and then edit your question, above, providing a self-contained minimal reproducible example that demonstrates your compilation error.Sam Varshavchik
Docs claim it should work for lambdas (emphasis added): "Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members." It includes an example which stores such a lambda directly, so it should work just fine.ShadowRanger
@SamVarshavchik: Provided code exhibit the issue. but error message is not clear and misleads OP.Jarod42

1 Answers

9
votes

Your problem is that only one user conversion is allowed and you need two:

  • lamba -> std::function -> A.

Both

A a{[](std::string) {}};
MyFunc({[](std::string) {}});

work.