This is my code:
#include<iostream> struct Item { int val; }; struct XItem { int val; }; void transform(const Item &i, XItem &target) { target.val = i.val; } template<typename T> void show(const T &v) { std::cout << v.val << std::endl; } template<typename ParamsType, typename ResultType> void handleRequest(Item &cur, ResultType (*impl)(const ParamsType &p)) { ParamsType p{}; transform(cur, p); ResultType res = (*impl)(p); show(res); } struct ResItem { int val; }; int main(int argc, char *argv[]) { Item i{42}; handleRequest(i, [](const XItem &x) { return ResItem{x.val}; }); return 0; } Compiling it gives the following error:
test.cpp:33:3: error: no matching function for call to 'handleRequest' handleRequest(i, [](const XItem &x) { ^~~~~~~~~~~~~ test.cpp:21:6: note: candidate template ignored: could not match 'ResultType (*)(const ParamsType &)' against '(lambda at test.cpp:33:20)' void handleRequest(Item &cur, ResultType (*impl)(const ParamsType &p)) { ^ I am unsure why this happens, however I do suspect that because the lambda, while being implicitly convertible to a function pointer, isn't one, the template parameters can't be deduced from it.
I tried using std::function<ResultType(const ParamsType &p)> instead, which also doesn't work. This question details the problem, so I tried to use its solution:
template<typename ParamsType, typename ResultType, typename Callback> void handleRequest(Item &cur, Callback cb) { ParamsType p = transform(cur); ResultType res = std::invoke(cb, p); show(res); } However, now ParamsType and ResultType cannot be implicitly deduced from the callback, I would need to give them explicitly. But I really want to infer ResultType because in the actual code, it can be quite lengthy (it is inferred from the lambda return statement, which is more complex than in this minimal example). I need the two types because both transform and show are overloaded and need the types to bind.
Is it possible to have handleRequest infer those types in this scenario and if so, how?
auto p = transform(cur); auto res = cb(p);?decltypeA transform(const Item&) {…},B transform(const Item&) {…}which would be illegal.handleRequestis vastly simplified. In actual code,transform(cur, p);iscur.get_to(p);from this json library which limits my possibilities. I gave the body to show how I use the types, not for getting advice of how not to use them there, I am sorry if that wasn't clear.