I'm sure the error is very simple and silly, but I can't see one. Here's the code:
#include <future>
template <typename ResultType>
class Foo
{
public:
template <typename ...Args>
void exec(const std::function<ResultType(Args...)>& task, Args&&... args) {}
};
int main()
{
Foo<void>().exec([](){});
return 0;
}
And here's the error:
'void CAsyncTask::exec(const std::function &,Args &&...)' : could not deduce template argument for 'const std::function &' with [ ResultType=void ]
Foo<void>().exec<void>([](){})
doesn't work either (and I'd much prefer not having to specify the Args
types manually).
Update regarding the suggested answer: the following code does indeed work.
CAsyncTask<void>().exec(std::function<void ()>([](){}));
But is there really no workaround for this problem? Can I expand my template somehow to deduce the lambda arguments?
As Pradhan mentionned, the exact type of the
std::function
cannot be inferred from the lambda. You can cast it explicitly to solve the issue:Alternatively, you can simply use another typename for the function, without creating a
std::function
:Then
Callable
will accept several types of functors, including lambdas.Note that there is a small performance penalty in using
std::function
objects in comparison to the template solution.You could also add a static_assert to ensure that your
Callable
can be called with the given arguments, and display a meaningful message otherwise, rather than letting the compiler generate one at the actual call.