如何使用编译时索引参数迭代参数包的大小

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

我正在尝试编写一个可变参数模板函数,其中包含一个循环,该循环遍历参数包中的每种类型。我正在使用它来构建一个元组,然后我在确定模板类型的回调函数上 apply

我想我可以使用 sizeof...(Args) 来做到这一点,如下所示:

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));
        });
}

这不会编译,因为 std::get<i>(args) 需要 i 作为编译时常量。但是,所有信息在编译时都是可用的。有没有办法使这项工作?我考虑过使用折叠表达式,但是

我正在使用 C++17。

可以定义辅助函数,使用index_sequence展开Tuple的元素,通过折叠表达式.

赋值
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));
  });
}

在 C++20 中,您只需在函数内定义模板 lambda 即可。