В одномерном случае, для обёрток такого рода предназначен
std::span. В многомерном случае, -
std::mdspan.
Что касается вашего кода. Первый случай немного некорректный (да, массив преобразуется к указателю на свой первый элемент, и хотя обратное, строго говоря, неверно, но...). Второй случай сильно некорректный, к примеру, для иллюстрации различия между
T(&)[total_size()] и
*this, если ваш код немного модифицировать:
template<class T, size_t N, size_t ... SIZES>
struct alignas(32) Array : std::array<Array<T, SIZES ...>, N>; //....
template<class T, size_t N>
struct alignas(32) Array<T, N> : std::array<T, N>; //...
То всё развалится, в частности,
(&a[1][0] - &a[0][2]) != 1.
В общем, если у Вас C++23, то
std::mdspan и/или
std::span (есть уже в С++20).
Если Вам требуются более ранние версии, то по их примеру, следует переопределять операторы `[]` над базовым плоским представлением. Это несильно сложнее, и тогда всё будет честно и прозрачно.