C++ 14 constexpr std::array

128
26 апреля 2019, 08:50

Изучаю constexpr. Не могу понять, почему компилятор не рассматривает одно из выражений как константное, потому что оно подходит под требования.

Код:

#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;
}

Можно скомпилировать по этой ссылке

В той реализации stl, с которой я работаю у array функция at объявлена как constexpr и у array нету конструкторов вообще, деструтор тоже не объявлен, а значит класс имеет деструктор по умолчанию, сам массив инициирован, поэтому я не знаю, почему это не работает.

Интересуют компиляторы gcc 5.4.0 и gcc 6.4.0. clang тоже это не компилирует.

Answer 1

Концепция "constexpr-ссылки" относится к свойствам самой ссылки, а не ссылаемого выражения. Constexpr-ссылка предполагает, что такая ссылка будет привязана к объекту, чье положение в памяти известно на стадии компиляции. Ситуация практически полностью аналогична таковой с constexpr-указателями.

Ваш локальный объект c этому требованию не удовлетворяет.

Объявите c как

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

и вы сможете привязывать к нему и его подобъектам constexpr ссылки.

(Иллюстрируя дополнительными примерами...) Вот такой код является корректным, несмотря на то, что ссылка привязывается к обычной неконстанстной переменной

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

А вот такой код не является корректным, сколько бы const и constexpr мы бы на переменную ни навешивали

int main()
{
  constexpr int y = 42;
  constexpr const int &ry = y;
}
READ ALSO
CryptEncodeObjectEx segfault при обращении

CryptEncodeObjectEx segfault при обращении

CryptEncodeObjectEx разваливается при обращении, параметры не влияют, как выяснилосьСобираю gcc-tdm, через Code::Blocks, что опробовано:

128
Определение pure virtual function

Определение pure virtual function

Недавно обнаружил, что можно дать определение для pure virtual function вне класса:

131
How to sort Map by Key, but with two conditions in Java?

How to sort Map by Key, but with two conditions in Java?

У меня есть проблема в сортировке MapИмеется LinkedHashMap с ключами типа "September-2018", "October-2018", "November-2017", "November-2018"

121