Выражение 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
не является объектом!