Variadic template function accepting lambda

c++, c++11, lambda, templates, variadic-templates

Solution

The problem with variadic templates in your case is that the compiler does not know whether the `int` you explicitly specified is the complete list for `ResultTypes...` or not, so it tries to deduce the optional remaining arguments from the parameter you gave it, and that obviously fails. This is a common pitfall with variadic template arguments and it is not limited to lambdas.

A solution always implies that you take away this option from the compiler, e.g.

template<typename ... ResultTypes>
void executeWithResultHandler_impl(std::function<void (ResultTypes...)> lambda)
{
}

template<typename ... ResultTypes, typename F>
void executeWithResultHandler(F&& lambda)
{
    executeWithResultHandler_impl(std::function<void (ResultTypes...)>(lambda));
}

Problem

I'm trying to understand the compiler error that I'm getting fo the code below. I've got a variadic template function which accepts a lambda with the specified types, and attempting to call that function results in the template not being considered a valid candidate due to a mismatch. ``` #include <functional> template<typename ... ResultTypes> void executeWithResultHandler(std::function<void (ResultTypes...)> lambda) { } int main(int argc, char **argv) { executeWithResultHandler<int>([] (int arg) { }); return 0; } ``` This results in the following error: ``` $ c++ -std=c++11 reduction.cpp reduction.cpp:10:5: error: no matching function for call to 'executeWithResultHandler' executeWithResultHandler<int>([] (int arg) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ reduction.cpp:4:6: note: candidate template ignored: could not match 'function<void (int, type-parameter-0-0...)>' against '<lambda at reduction.cpp:10:35>' void executeWithResultHandler(std::function<void (ResultTypes...)> lambda) ^ 1 error generated. ``` If I change the declaration to not be variadic: ``` template<typename ResultType> void executeWithResultHandler(std::function<void (ResultType)> lambda) { } ``` then it works for the toy example above, but for the real problem I need arbitrary arguments. Is there something I’m missing here, or anther way to accomplish this? EDIT: This was marked as a duplicate incorrectly, I believe- the dupe does not answer the question I'm asking. This question specifically has to do with the variadic template issue here: Please note that, when I switch the template to be non-variadic the lambda converts to the std::function type correctly, as expected. This is true regardless of the number of arguments, as long as that is not handled in a variadic fashion. However, it does not work with the variadic version specifically, despite an expectation that the parameter pack is unpacked to a set of real parameters, and the explicit specification of the template parameter list at the function call site.

Original source

Related problems