Мне нужен многомерный массив, и я хотел использовать современный C ++ (например, std::array
для получения итераторов, размера, данных, ...)
Решение, к которому я пришел, в основном такое же, как и в Элегантно определяйте многомерный массив в современном C ++ , но с хорошим использованием шаблонов:
namespace detail {
template<typename T, size_t T_n1, size_t... T_n>
struct GetMultiArrayType
{
using type = std::array<typename GetMultiArrayType<T, T_n...>::type, T_n1>;
};
template<typename T, size_t T_n>
struct GetMultiArrayType<T, T_n>
{
using type = std::array<T, T_n>;
};
} // namespace detail
/// Wrapper around std::array to allow multi-dimensional fixed-size arrays
/// The declaration 'FooBar myVar[N1][N2][N3]' can be replaced with 'MultiArray<FooBar, N1, N2, N3> myVar'
template<typename T, size_t... T_n>
using MultiArray = typename detail::GetMultiArrayType<T, T_n...>::type;
Пока все хорошо.Но теперь синтаксис инициализации убивает меня:
У меня есть много констант в коде, которые определяют такие мульти-массивы, например, для точек.Класс Point - это просто структура с x
и y
и некоторыми преобразованиями и математическими операторами, плюс ctor, принимающий x
и y
.
Старый код, использующий массивы C, выглядит следующим образом:
const Point offsets[2][3] = {{{24, -41}, {19, -41}, {31, -88}},
{{-9, -49}, {14, -59}, {16, -63}, {0, -44}}};
Это нормально.Если бы я должен был инкапсулировать массив C в класс, подобный std::array
, но с несколькими измерениями (struct MultiArrayRaw{ Point data[2][3]; ...};
), мне нужна дополнительная пара фигурных скобок.AFAIK brace-elision здесь не применяется, потому что мой «нижний» тип - Point
, который сам по себе является совокупным.Так это выглядит так:
const MultiArrayRaw<Point,2,3> offsets = {{{{24, -41}, {19, -41}, {31, -88}},
{{-9, -49}, {14, -59}, {16, -63}, {0, -44}}}};
Это нехорошо ... Но становится еще хуже, если я использую MultiArray
, то есть std::array<std::array...
, где мне нужна еще 1 пара скобок.Гораздо хуже для 3D, 4D ... массивов.
Итак, вопрос: как можно элегантно / читабельно инициализировать массив констант ND агрегатов (Point
)?
Дополнительно: Нетплохой трюк, так что компилятор все еще может проверять наличие ошибок со многими значениями и тому подобное.