Search code examples
c++lambdac++17template-argument-deductiongeneric-lambda

How to pass a template lambda to a function and use it with different types


I have this code inherited from old C++ time using macros. I'm currently replacing it, and I'm at the point where some constructs need to be factored.

Typically, I have this:

if(condition)
{
    fun1(fun2(arguments, arg1)); // let's say arg1 is a vector of doubles
}
else
{
    fun1(fun2(arguments, arg2)); // let's say arg2 is a double
}

several times. fun1() has a different set of arguments depending on fun2() argument types, and I could have arg1 and arg2 there as well (the true code actually has several layers of ifs with each time a different set of types, several additional layers of functions inside each branch).

I'd like to factor this one out in a function that can take a template lambda like this:

[&](auto arg) { fun1(fun2(arguments, arg));}

Now, the issue is that this is templated, so I can't turn it into a std::function, so I don't know what kind of argument I should use to create my function:

void dispatch(bool condition, const std::vector<double>& arg1, double arg2, ???? lambda)
{
    if(condition)
    {
        lambda(arg1);
    }
    else
    {
        lambda(arg2);
    }
}

Is there such an option in C++17? or even C++20?


Solution

  • Now, the issue is that this is templated, so I can't turn it into a std::function, so I don't know what kind of argument I should use to create my function

    What about simply as follows ?

    template <typename F>
    void dispatch(bool condition, const std::vector<double>& arg1, double arg2, F lambda)
    

    I mean... you can see a lambda function almost as syntactic sugar for an object of a class with an operator() (a template operator() in case of a generic-lambda).

    So you can intercept a lambda simply through the template type of the class.

    Maybe you can accept it as const reference (F const & lambda), if lambda is not mutable, to avoid unnecessary copies.

    Is there such an option in C++17? or even C++20?

    Should works starting from C++14. Before C++14, generic lambda are unavailable (but you can substitute them with explicit classes with template operator()s).