https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71504
Will <will at dash dot org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |will at dash dot org --- Comment #4 from Will <will at dash dot org> --- A motivating example for this error to be given higher priority. An array_ref wrapper for multidimensional C-arrays T[M][N]... providing constexpr access via an index operator[] -> returns array_ref<T> when T is an array type or -> returns T& otherwise for non-array T https://wandbox.org/permlink/vcAokwqzk5tOF1ok #include <type_traits> template <typename T> struct array_ref; template <typename T> using ref_t = std::conditional_t< std::is_array_v<T>, array_ref<T>, T&>; template <typename T, unsigned N> struct array_ref<T[N]> { T* a; // T (&a)[N]; using const_reference = const ref_t<T>; constexpr const_reference operator[](unsigned I) const { return {a[I]}; } }; template <typename A> array_ref(A&) -> array_ref<A>; constexpr int a2[2] = {1,2}; static_assert( array_ref{a2}[0] == 1 ); constexpr int a22[2][2] = {{1,2},{3,4}}; static_assert( array_ref{a22}[0][0] == 1 ); > error: non-constant condition for static assertion static_assert( array_ref{a22}[0][0] == 1 ); > error: accessing value of 'a22' through a 'const int' glvalue in a constant > expression Clang accepts. (MSVC untested.) A workaround is to replace the pointer member with a reference member (a reference member is less flexible and generally discouraged). So GCC with this bug forces the less flexible implementation afaict - I couldn't find a workaround that uses a pointer member. Like std::array, array_ref is intended to provide array copy. This is why >1D index operations return wrapped array_ref<T> (the wandbox link includes some static_asserts to illustrate). Constexpr is a requirement for my application; a reasonable requirement for a wrapped C-array. Other multi-dimensional array implementations must've hit this