barney
barney

Reputation: 2202

C++ how to wrap a variadic function template's parameter pack -> into a lambda

I want to build a functon template that takes any function pointer & its arguments list - and returns a (stateful) lambda that binds those arguments values inside (think std::bind but lambda-based)

#include <iostream>
#include <vector>

template <class ...D>
class DEB;

template <class Ret, class ... Args>
auto getLambdaFromFunction(Ret(*func)(Args...)) {
    return [func](Args ... ar){ // auto could work here but lambda is anyway templated by external template's Args
        func(ar...);
    };
}

template <class Ret, class ... Args>
auto wrapFunction(Ret(*func)(Args...),Args... args) {
    return [=](){
        func(args...);
    };
}

int doone(int a, float b) {
    std::cout << "do one";
    return a;
}

int main() {
    auto lw = getLambdaFromFunction(doone); // compiles
    lw(1,2.); // invokation works

    auto lambda_parameters_binded = wrapFunction(doone, 1,2.); // **ERROR**: no matching function for call
lambda_parameters_binded(); // see mom, no hands ie no arguments!
}

I believe I need to make somehow the variadic arguments to be captured inside the lambda in wrapFunction the default [=] capture seems not to understand variadic argument list

Upvotes: 1

Views: 1603

Answers (2)

super
super

Reputation: 12928

Another solution could be to have the function parameters, and the passed in parameter in different variadic template packs. That way there will be no ambiguity to generate the template function.

template <class Ret, class ... Args, class ... Params>
auto wrapFunction(Ret(*func)(Args...),Params... params) {
    return [=](){
        func(params...);
    };
}

Upvotes: 2

user7860670
user7860670

Reputation: 37468

You should read the error description carefully, right now function accepts float, but you are passing double as a third parameter. Passing float will make it work:

auto lambda_parameters_binded = wrapFunction(doone, 1, 2.0f);

Run in online compiler

Also note that generated lambda does not return anything, you should add another return statement inside of lambda body:

return
(
    [=](void)
    {
        return(func(args...));
    }
);

Upvotes: 5

Related Questions