Reputation: 7502
I am trying to execute the following code in C++. The program converts a lambda with no capture to a function pointer.
#include <utility>
template <typename R, typename... Args>
R run(R (*func)(Args...), Args&&... args) {
func(std::forward<Args>(args)...);
}
int main() {
run([] (int x, int y) {
return x + y;
}, 100, 200);
return 0;
}
However, when I compile it, I get the following error -
test.cc: In function ‘int main()’:
test.cc:11:20: error: no matching function for call to ‘run(main()::<lambda(int, int)>, int, int)’
}, 100, 200);
^
test.cc:11:20: note: candidate is:
test.cc:4:3: note: template<class R, class ... Args> R run(R (*)(Args ...), Args&& ...)
R run(R (*func)(Args...), Args&&... args) {
^
test.cc:4:3: note: template argument deduction/substitution failed:
test.cc:11:20: note: mismatched types ‘R (*)(Args ...)’ and ‘main()::<lambda(int, int)>’
}, 100, 200);
^
As far as I am aware this is fine. I have also tried explicitly giving the template arguments in the call to run
. That doesnt work either.
Any ideas?
Upvotes: 1
Views: 87
Reputation: 303890
A lambda is not a function pointer. It cannot be deduced as a function pointer. It is a closure. However, if (and only if) it takes no capture, it can be explicitly converted to a function pointer via some sorcery:
run(+[] (int x, int y) {
// ^^^
return x + y;
}, 100, 200);
That said, it'd be better to simply have run
take an arbitrary callable:
template <typename F, typename... Args>
auto run(F func, Args&&... args)
-> decltype(func(std::forward<Args>(args)...)) // only for C++11
{
return func(std::forward<Args>(args)...);
}
Upvotes: 4