如何实现支持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
Sizestemplate 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{}.
- Default constructor initializes all array elements to
- 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
constexprsupport ofstd::array,std::initializer_list, and fold expressions. - Excess elements in initializer lists are ignored to prevent overflow.
- The internal storage uses a
std::tupleofstd::arrayobjects, which is the most efficient way to handle heterogeneous array sizes in a constexpr context.
内容的提问来源于stack exchange,提问作者Bondrewd
相关产品推荐
相关产品推荐

