C++ 14 constexpr std::array

I'm studying constexpr. I can't understand why the compiler doesn't treat one of the expressions as a constant, because it fits the requirements.

Code:

#include <iostream>
#include <cstdlib>
#include <array>

constexpr int f( int x ) 
{
    if ( x < 0 ) x = 0;
    return ++x;
}

int main()
{
    typedef double  T;
    typedef std::array<T, 3> C;

    constexpr C c = {1, 2, 3};
    constexpr C::const_reference ref = c.at( 0 ); //  error: is not a constexpr

    static_assert( ref == 1, "ref != 1" );

    constexpr int y = -3;
    //y = f( y );
    static_assert( f( y ) == 1, "f( y ) != 1" );

    return 0;
}

You can compile from this link

In the stl implementation I'm working with, array's at function is declared as constexpr and array has no constructors at all, the destructor is also not declared, which means the class has a default destructor, the array itself is initiated, so I don't I know why it doesn't work.

I am interested in the gcc 5.4.0 and gcc 6.4.0 compilers. clang does not compile this either.

Author: OlegUP, 2018-11-17

1 answers

The concept of a "constexpr reference" refers to the properties of the reference itself, not the referenced expression. A Constexpr reference assumes that such a reference will be bound to an object whose position in memory is known at the compilation stage. The situation is almost completely similar to that with constexpr pointers.

Your local object c does not meet this requirement.

Declare c as

static constexpr C c = {1, 2, 3};

And you will be able to link him to it as well. subobjects constexpr references.


(Illustrating with additional examples...) This code is correct, despite the fact that the reference is bound to the usual non-constant variable

int main()
{
  static int x = 42;
  constexpr const int &rx = x;
}

But this code is not correct, no matter how many const and constexpr we would hang on the variable

int main()
{
  constexpr int y = 42;
  constexpr const int &ry = y;
}
 1
Author: AnT, 2018-11-19 08:05:43