Der Ausdruck b
in diesem Code wirdWarum ist dieser Ausdruck kein konstanter Ausdruck?
int main()
{
constexpr int a = 10;
const int &b = a;
constexpr int c = b; // here
return 0;
}
ein Kern konstanter Ausdruck sein, da der Standard sagt (8.20 Absatz 2 [expr.const] in n4700)
Ein Ausdruck
e
ist a Kernkonstante Ausdruck, es sei denn die Auswertung vone
würde einen der folgenden Ausdrücke auswerten:
...
ein L-Wert-zu-R-Wert-Umwandlung (7.1), es sei denn, es zu
...
angewendet wird ein nichtflüchtiges glvalue, das sich auf bezieht, ein nichtflüchtiges Objekt, das mit constexpr definiert ist, oder das sich auf ein nicht veränderbares Unterobjekt eines solchen O bezieht bject oder
Zuerst wird der Ausdruck b
in dem obigen Code ist ein L-Wert (der auch ein glvalue ist), da es eine Referenz ist, wodurch eine Variable ist (8.1.4.1, Absatz 1 [expr.prim.id.unqual]):
der Ausdruck ist ein L-Wert, wenn das Unternehmen eine Funktion ist, variable oder Datenelement und ein prvalue sonst; es ist ein Bitfeld, wenn die Kennung ein Bitfeld (11.5) bezeichnet.
Zweitens ist es die Aufgabe der variable b
bezeichnet ist a
, und es ist mit constexpr
erklärt. Allerdings gcc klagt
./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;
Soweit ich das beurteilen kann, eine Referenz ist kein Objekt, so dass die obige Kugel schlägt offenbar, dass a
wird mit constexpr
deklariert werden. Fehle ich etwas? Der Grund, warum ich mit gcc nicht einverstanden bin, ist, dass gcc b
als ein Objekt sieht, wodurch es mit constexpr
deklariert werden muss. b
ist jedoch kein Objekt!
Clang stimmt mit GCC überein. Aber ich denke, ich stimme dir zu, das ist ein Fehler entweder im Standard oder in den Compilern. Beachten Sie auch, dass MSVC den Code akzeptiert. –