Cannot construct constexpr array from braced-init-list
The compiler is complaining that the initializer of a.p
is not a constant expression. It's failing ยง5.20/5.2:
if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value
In other words, only pointer values known to the linker are valid constants. (Also, in your example the pointer is dangling.)
The first static_assert
doesn't trip this because p
is discarded and the value of n
is a constant expression. Constant expressions may have non-constant subexpressions.
This works:
static constexpr double arr[] = { 1.,2.,3. };constexpr const_array<double> a{ arr };static_assert( a.size() == 3 );
Credit to @Jarod42 for pointing out the issue in the comments.
The problem was that you cannot imbue the constant nature of the pointer to T in the inner template through the outer template's T parameter.
template <typename T> class const_array { const T * p; unsigned n;public: template <unsigned N> constexpr const_array(const T(& a)[N]): p(a), n(N) { }};int main(int argc, char* argv[]) { constexpr const_array<double> ca{(const double []) { 1., 2. }}; return 0;}
I tried a few dozen permutations to get rid of the cast without success.