I want to store a lambda expression in a function object, then retrieve its underlying function pointer. For reasons I do not understand, function::target() is a templated function that returns nullptr if the incorrect type is passed in (I'm working in C++11).
I have a vague understanding of how lambdas are expressions that result in temporary functions that are bound to namespaces and thus have a different type depending on which namespace they reside in. I have no idea if that impression is correct or how to apply it to what I use in the template argument. Any insight into what C++ magic is going on here would be greatly appreciated.
void foo(int) { std::cout << "foo" << std::endl; }
int main() {
std::function<void(int)> a(foo); // well-defined global function
std::function<void(int)> b([](int) -> void {}); // temporary lambda expression
auto bar = [](int) -> void {}; // lambda expression stored in variable
std::function<void(int)> c(bar);
std::cout << a.target<void(*)(int)>() << std::endl; // 0x7ffe8e74ecf0
std::cout << b.target<void(*)(int)>() << std::endl; // 0
std::cout << c.target<void(*)(int)>() << std::endl; // 0
std::cout << &bar << std::endl; // 0x7ffe8e74ecef
return 0;
}
The result of a lambda expression is an object, not a function.
Every lambda expression has a unique but unnamed type.
You can recover an object from c
since bar
has a name; c.target<decltype(bar)>()
returns a pointer to an object of that type (note that it's not a function pointer).
You can't recover the object in b
since you can't describe its type.