Выражение b в этом коде должно быть выражением постоянной константы
int main()
{
constexpr int a = 10;
const int &b = a;
constexpr int c = b; // here
return 0;
}
так как стандарт говорит (8.20, параграф 2 [expr.const] в n4700)
Выражение
eявляется выражением постоянной константы, если оценкаeбудет оценивать одно из следующих выражений:
...
преобразование lvalue-to-rvalue (7.1), если оно не применяется к
...
неизменяемый glvalue, который ссылается на энергонезависимый объект, определенный с помощью constexpr, или который ссылается на не изменяемый подобъект такого объекта, или
Во-первых, выражение b в приведенном выше коде является lvalue (которое также является glvalue), поскольку оно является ссылкой, тем самым являясь переменной (8.1.4.1, абзац 1
[Expr.prim.id.unqual]):
Выражение представляет собой lvalue, если объект является функцией, переменная, или элемент данных и значение prvalue иначе; это бит-поле, если идентификатор обозначает бит-поле (11.5).
Во-вторых, объект, обозначаемый переменной b, является a, и он объявлен с помощью constexpr. Однако gcc жалуется
./hello.cpp: In function ‘int main()’:
./hello.cpp:6:20: error: the value of ‘b’ is not usable in a constant expression
constexpr int c = b;
^
./hello.cpp:5:13: note: ‘b’ was not declared ‘constexpr’
const int &b = a;
Насколько я могу судить, ссылка не является объектом,, поэтому вышеуказанная марка, по-видимому, предполагает, что a объявляется с помощью constexpr. Я что-то упускаю? Причина, по которой я не согласен с gcc, состоит в том, что gcc видит b как объект, тем самым требуя, чтобы он был объявлен с помощью constexpr. Однако b не является объектом!