Home > Mobile >  How to iterate over the size of a parameter pack with a compile-time index parameter
How to iterate over the size of a parameter pack with a compile-time index parameter

Time:11-17

I'm trying to write a variadic template function that includes a loop that iterates over each type in the parameter pack. I'm using this to build up a tuple which I then apply on the callback function which determined the template types.

I thought I could do this using sizeof...(Args) as follows:

template <typename ...Args>
void addCallback(void* handle, std::string address, std::function<void(Args...)> callback)
{

    return addMessageCallback(std::move(address), [callback](const ci::osc::Message& message) {
        std::tuple<Args...> args;
        for (size_t i = 0; i < sizeof...(Args); i  )
        {
            std::get<i>(args) = message.getArg<std::tuple_element_t<i, decltype(args)>(i);
        }

        std::apply(callback, std::move(args));
        });
}

This doesn't compile because std::get<i>(args) requires i to be a compile time constant. However, all the information is available at compile time. Is there a way to make this work? I've thought about using a fold expression but

I'm using C 17.

CodePudding user response:

You can define a helper function to use index_sequence to expand the elements of Tuple and assign values through fold expression.

template<class Tuple, class Message, std::size_t... Is>
void assign_tuple(Tuple& tuple, const Message& message, std::index_sequence<Is...>) {
  ((std::get<Is>(tuple) = message.getArg<std::tuple_element_t<Is, Tuple>(Is)), ...);
};

template <typename ...Args>
auto addCallback(void* handle, std::string address, std::function<void(Args...)> callback) {
  return addMessageCallback(std::move(address), [callback](const ci::osc::Message& message) {
      std::tuple<Args...> args;
      assign_tuple(args, message, std::make_index_sequence<sizeof...(Args)>{});
      std::apply(callback, std::move(args));
  });
}

In C 20 you can just define template lambda inside the function to do this.

  • Related