Is there any way to recover type information from a lambda with default parameters stored in a std::function that does not have those parameters in its type?
std::function<void()> f1 = [](int i = 0){};
std::function<void(int)> f2 = [](int i = 0){};
std::function<void(int)> f3 = f1; // error
std::function<void()> f4 = f2; // error
Looking at std::function's copy constructor, there is no partial template specialization for other function types, so I'd imagine this information is lost and it is just a case that you can't assign a function of one type to a function of another type, even if internally they can both call the function. Is this correct? Are there any work-arounds to achieve this? I'm looking at std::function::target, but haven't had any luck, I'm no expert on function types and pointers.
On a side note, how does f1(or the lambda) bind the default parameter?
No, that is not possible, because default arguments are a property of a set of a function's declarations, not of the function itself. In other words, this is perfectly legal C++:
A.cpp
int f(int i = 42);
const int j = f(); // will call f(42)
B.cpp
int f(int i = 314);
const int k = f(); // will call f(314)
F.cpp
int f(int i = 0)
{
return i;
}
const int x = f(); // will call f(0)
These can all be linked together just fine.
Which means it's not possible to somehow "retrieve" a default argument from a function.
You can do the equivalent of f4 = f2
using std::bind
and providing your own default argument, like this:
std::function<void()> f4 = std::bind(f2, 42);
However, there is no way to get something equivalent to f3 = f1
.