You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持constexpr的C++可变大小数组集合模板类

Implementing a Constexpr ArraysCollection Template Class

Here's a complete implementation of the ArraysCollection template class that meets your requirements, compatible with C++17 and later:

#include <array>
#include <tuple>
#include <initializer_list>
#include <utility>

template <typename T, size_t... Sizes>
class ArraysCollection {
public:
    // Default constructor: value-initialize all arrays (zeros for arithmetic types)
    constexpr ArraysCollection() : data_{std::array<T, Sizes>{}...} {}

    // Constructor: initialize each array with provided elements, fill remaining with T{}
    constexpr ArraysCollection(std::initializer_list<T>... initLists)
        : data_{initializeArray<Sizes>(initLists)...} {}

    // Access the N-th array (mutable)
    template <size_t N>
    constexpr std::array<T, std::tuple_element_t<N, decltype(data_)>::size()>& get() {
        return std::get<N>(data_);
    }

    // Access the N-th array (const)
    template <size_t N>
    constexpr const std::array<T, std::tuple_element_t<N, decltype(data_)>::size()>& get() const {
        return std::get<N>(data_);
    }

    // Get the number of arrays in the collection
    static constexpr size_t arrayCount() noexcept {
        return sizeof...(Sizes);
    }

    // Iterate over all arrays with a callable function
    template <typename Func>
    constexpr void forEach(Func&& func) {
        std::apply([&func](auto&&... arrays) {
            (func(std::forward<decltype(arrays)>(arrays)), ...);
        }, data_);
    }

    // Const version of forEach
    template <typename Func>
    constexpr void forEach(Func&& func) const {
        std::apply([&func](const auto&... arrays) {
            (func(arrays), ...);
        }, data_);
    }

private:
    // Helper: Initialize an array from an initializer list, fill remainder with T{}
    template <size_t Size>
    static constexpr std::array<T, Size> initializeArray(std::initializer_list<T> list) {
        std::array<T, Size> arr{}; // Default-initialize all elements first
        size_t idx = 0;
        for (const auto& elem : list) {
            if (idx >= Size) break; // Ignore excess elements
            arr[idx++] = elem;
        }
        return arr;
    }

    // Internal storage: tuple of arrays with specified sizes
    std::tuple<std::array<T, Sizes>...> data_;
};

Key Features Explained

  • Variadic Template Support: The class accepts any number of array sizes via the Sizes template parameter pack.
  • Constexpr Compatibility: All constructors and member functions are constexpr, allowing compile-time initialization and operations.
  • Flexible Initialization:
    • Default constructor initializes all array elements to T{} (zero for numeric types).
    • Initializer list constructor lets you provide partial values for each array, with remaining elements auto-filled to T{}.
  • Access and Iteration:
    • get<N>() provides direct access to the N-th array (0-indexed).
    • forEach() allows iterating over all arrays with a custom function.

Usage Examples

Default Initialization

// Creates 4 arrays: 3 ints, 6 ints, 8 ints, 2 ints (all zeros)
constexpr ArraysCollection<int, 3, 6, 8, 2> myArrays;

// Verify compile-time values
static_assert(myArrays.get<0>()[0] == 0);
static_assert(myArrays.get<3>().size() == 2);

Partial Initialization

// Creates 2 float arrays: 2 elements and 3 elements
constexpr ArraysCollection<float, 2, 3> floatArrays {{-10.f}, {2.f, 3.14f}};

// Verify initialized values
static_assert(floatArrays.get<0>()[0] == -10.f);
static_assert(floatArrays.get<0>()[1] == 0.f); // Auto-filled
static_assert(floatArrays.get<1>()[1] == 3.14f);
static_assert(floatArrays.get<1>()[2] == 0.f); // Auto-filled

Iterating Over Arrays

#include <iostream>

int main() {
    ArraysCollection<int, 2, 4, 3> coll {{1}, {2,3}, {4,5,6}};

    coll.forEach([](const auto& arr) {
        std::cout << "Array size: " << arr.size() << ", elements: ";
        for (int elem : arr) {
            std::cout << elem << " ";
        }
        std::cout << "\n";
    });

    // Output:
    // Array size: 2, elements: 1 0 
    // Array size: 4, elements: 2 3 0 0 
    // Array size: 3, elements:4 5 6 
    return 0;
}

Notes

  • Requires C++17 or later for constexpr support of std::array, std::initializer_list, and fold expressions.
  • Excess elements in initializer lists are ignored to prevent overflow.
  • The internal storage uses a std::tuple of std::array objects, which is the most efficient way to handle heterogeneous array sizes in a constexpr context.

内容的提问来源于stack exchange,提问作者Bondrewd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 06:25:04