Search code examples
c++templatestuplesvariadic-templatesstd-function

Is there a way to expand and call a tuple of std::functions?


I have a class containing a tuple of functions, with their return types determined by the template of the class:

template <typename... Ts>
class A{
    static inline auto funcs = std::make_tuple(std::function<Ts()>()...)
};

I would like to be able to iterate over these functions. I tried getting the indexes of each type from the template using the method from this answer: https://stackoverflow.com/a/26169248/

std::get<Index<Ts,Ts...>::value>(funcs)()...;

But this code doesn't compile. It complains about the "..." at the end, possibly because the template parameter pack was already expanded when I typed "T...", but I don't see why it won't let me expand the other "Ts". Is there a way to do this?


Solution

  • You have to remove the {} in your funcs assignment otherwise this will create an initializer_list and not a tuple

    static inline auto funcs = std::make_tuple(std::function<Ts()>()...);
    

    Then you can call each tuple function with help of std::apply and a generic variadic lambda:

    auto call = [](auto&&...funcs) {
        (funcs(),...);
    };
    
    int main()
    {
        A<int, float, char> l;
        std::get<0>(l.funcs) = []() { cout << "Calling int()" << endl; return 1; };
        std::get<1>(l.funcs) = []() { cout << "Calling float()" << endl; return 1.f; };
        std::get<2>(l.funcs) = []() { cout << "Calling char()" << endl; return '1'; };
    
        std::apply(call, l.funcs);
        return 0;
    }
    

    See the live example: https://onlinegdb.com/HJfQ95TpS