2017-04-21 9 views
4

Ist es erlaubt, eine nicht-const Referenz als constexpr zu deklarieren? Beispielcode:consExpr Verweis auf nicht-const Objekt

int x = 1; 
constexpr int& r = x; 

Diese von gcc und Klirren akzeptiert wird (Ich habe versucht, mehrere aktuelle und frühere Versionen der beiden, zurück zu C++ 11 und akzeptiert es). Aber ich denke, ihm nicht akzeptiert werden soll, weil C++ 14 [dcl.constexpr/9] sagt:

wenn ein constexpr Spezifizierer in einer Referenz Erklärung verwendet wird, jeder Voll Ausdruck, der in seinem initializer erscheint soll ein konstanter Ausdruck sein

und x ist kein konstanter Ausdruck.

Die Sprache in der neuesten C++ 17 Entwurf von [dcl.constexpr] geändert und erwähnt nicht einmal constexpr Referenzen explizit mehr, ich kann nicht Kopf oder Schwanz von dem, was es über sie versucht zu sagen .

+1

Wer sagt, 'x' ist kein konstanter Ausdruck? –

+0

"x ist keine Kernkonstante Ausdruck" –

+0

@ T.C. [expr.const]/2 "' e "ist ein Kernkonstantenausdruck, es sei denn, die Auswertung von 'e' würde eine der folgenden Aussagen auswerten: [...] eine lvalue-to-rvalue-Konvertierung, es sei denn, sie wird auf [cases angewendet dass dieser Code nicht übereinstimmt] " –

Antwort

4

Unter der Annahme, dass x statische Speicherdauer hat, ist der Lvalue-Ausdruck x ein perfekt gültiger konstanter Ausdruck.

Wenn Sie x in einem Kontext verwenden, die eine prvalue erfordert, was bewirkt, dass der L-Wert-to-rvalue Umstellung auf sie angewendet werden soll, dann wird die resultierende prvalue Ausdruck - nennen es TO_RVALUE(x) - wäre nicht ein konstanter Ausdruck sein, aus offensichtlichen Gründe dafür. Im Falle der Referenzbindung gibt es jedoch keine solche Umwandlung.

+0

Kommt es auf den Initialisierer an? (Z. B. macht 'int x = rand();' immer noch 'x' einen konstanten Ausdruck?) –

+0

@ M.M Nr. (Ja.) Ein lvalue-Konstantenausdruck bezeichnet lediglich die Entität (im Grunde ist es wie ihre Adresse). Worauf es initialisiert wird, ist irrelevant und muss dem Compiler nicht einmal bekannt sein (z. B. "extern int x;" ist ausreichend). –

Verwandte Themen