有没有办法使用相同的索引迭代 std::tuple 和 std::array ?

Dam*_*ian 5 c++ template-meta-programming variadic-templates stdtuple c++20

我正在编写一个简单的实体组件系统框架,我想在其中使用可变参数模板来获得更灵活的接口。对于每个组件,我都有偏移量(从块内存的开始)存储在std::array. 在我的 'update()' 方法中,我想从这个数组中读取偏移量,将它添加到块的指针并将指针(指向特定组件)作为参数直接传递给 lambda。我尝试使用std::index_sequence,但无法同时使用此索引作为元组和数组的索引。预先感谢您的帮助。

    template<typename ...Cn>
    class SystemGroup {
        public:
            using OffsetArray = std::array<uint16_t, sizeof...(Cn)>;

            static constexpr size_t kMaxGroups = 16;
            static constexpr GroupIndex kInvalidIndex = -1;

            struct Group {
                static constexpr uint8_t kNumComponents = sizeof...(Cn);

                OffsetArray componentOffsets;
                Chunk *pFirstChunk;
            };
    };

    template<typename ...Cn>
    void SystemGroup<Cn...>::update() {
        for (auto group : m_groups) {
            // iterate over archetype's chunks
            ecs::Chunk *pChunk = group.pFirstChunk;
            do {
                // get component data
                std::tuple<Cn*...> pointers;
                
                // Here is the problem. I don't know how to iterate over tuple and array using variadic templates
                // pointers[0] = pChunk->memory + m_groups.componentOffsets[0];
                // pointers[1] = pChunk->memory + m_groups.componentOffsets[1];
                // pointers[sizeof..(Cn)] = pChunk->memory + m_groups.componentOffsets[sizeof..(Cn)];

                auto updateComponents = [](int *pIntegers, float *pFloats) {
                };
                std::apply(updateComponents, pointers);
                pChunk = pChunk->header.pNext;
            } while(pChunk);
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑谢谢大家的帮助。我决定选择 max66 提出的解决方案。当然,我拆分了 lambda 的定义和调用以使其更具可读性。

Hol*_*Cat 2

添加一些辅助函数:

template <typename Integer, Integer ...I, typename F>
constexpr void constexpr_for_each(std::integer_sequence<Integer, I...>, F &&func)
{
    (func(std::integral_constant<Integer, I>{}) , ...);
}

template <auto N, typename F>
constexpr void constexpr_for(F &&func)
{
    if constexpr (N > 0)
        constexpr_for_each(std::make_integer_sequence<decltype(N), N>{}, std::forward<F>(func));
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

constexpr_for<sizeof...(Cn)>([&](auto index)
{
    constexpr auto i = index.value;
    std::get<i>(pointers) = pChunk->memory + m_groups.componentOffsets[i];
});
Run Code Online (Sandbox Code Playgroud)