2016-05-03 9 views
3

Ich habe folgende Codewarum rvalue nicht zuweisen Referenzvariable constexpr

constexpr int into(int a,int b) 
{ 
    int c=a*b; 
    return c; 
} 

int main() 
{ 
constexpr int &n=into(5,5); 

} 

und ich habe (in MSDN)

Das Schlüsselwort constexpr eingeführt wurde in C++ 11 und verbessert in C++ 14. Es bedeutet konstanten Ausdruck. Wie const kann es auf Variablen angewendet werden, so dass ein Compilerfehler ausgelöst wird, wenn ein Code versucht, den Wert zu ändern.

Nachdem ich es las, dachte ich, dass constexpr kann anstelle von const verwendet werden, aber für den obigen Code erhalte ich einen Compiler-Fehler unter Angabe

`int main()': 
invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'` 

Wenn constexpr mit Fassung const, es funktioniert gut. Ich verstehe dieses Verhalten nicht; Kann jemand Licht abwerfen?

+1

Eine 'constexpr'-Referenz muss an eine globale Variable gebunden werden. Siehe Antwort [hier] (http://stackoverflow.com/a/28614655/1460794). – wally

+0

@ flatmouse, danke für die Wiederholung ... eine der Antworten im Link sagt "Eine Referenz ist konzeptionell gleichbedeutend mit der Adresse der Variablen, und die Adresse einer lokalen Variablen ist keine Konstante" hier, wenn ich const es bindet. aber nicht nur für den constexpr.i glaube das Verhalten von const und consxpr zu einer Variablen ist das gleiche –

+0

Das Problem könnte sein, dass der Rückgabewert von 'in' nirgends gespeichert wird, aber Sie speichern einen Verweis auf diesen Rückgabewert, so Wohin muss diese Referenz verweisen? – Oebele

Antwort

3

Ausdrücke, die als constexpr markiert sind, werden zur Kompilierungszeit aufgelöst, wodurch das Ergebnis into(5,5) als int Literal behandelt wird. Wie wir wissen, können Referenzen nicht an ein int Literal in C++ gebunden werden.

Sie diese Arbeit machen könnte constexpr int x=into(5,5); indem sie erscheinen im globalen Bereich und innerhalb der Haupt eine constexpr const int Bezug auf x Schaffung x zwingen, bevor main gelöst werden aufgerufen, die dann ein Verweis auf x gebunden sein erlaubt:

constexpr int into(int a,int b) { 
    int c=a*b; 
    return c; 
} 

// guaranteed to be resolved before main is called 
constexpr int x = into(5,5); 

int main() { 
constexpr const int& n = x; 
static_assert(n == 25, "whoops!"); 
} 

Um Ihre Frage speziell zu beantworten, ist dies vollständig orthogonal zu Rvalues ​​oder verschieben Semantik, sondern ist eine Nuance von constexpr.

Wenn globale Scoping Sie Sodbrennen gibt, könnten Sie x ein static sowie machen und vor seine Referenz setzen ihre Initialisierung Bindung, die mir natürlicher scheint:

constexpr int into(int a,int b) { 
    int c=a*b; 
    return c; 
} 

int main() { 
// guaranteed to be resolved before main is called 
static constexpr int x = into(5,5); 
constexpr const int& n = x; 
static_assert(n == 25, "whoops!"); 
} 
+1

"* Wie wir wissen, können Referenzen nicht an ein int-Literal in C++ gebunden werden." *, Welche Verweise meinen Sie? –

+1

@ erip, die Dinge nicht klar, Sie sagten 'in (5,5) als int literal. Wie wir wissen, können Referenzen in C++ nicht an ein int-Literal gebunden werden. ich glaube, die Funktion into() aufzurufen, die int && zurückgibt, was ein rvalue ist, und es sollte einer konstanten Referenz zugewiesen werden. Die Dinge liefen gut, wenn ich const int & n = in (5,5) setzte; inside main..if const kann warum kann nicht der constexpr war der constexpr fehlt etwas, um mit diesem Fall zu tun –

+0

@PiotrSkotnicki ich meine Verweise auf 'int' Literale. :) 'int & x = 25;' ist nicht legal. Sie können sicherlich "const" Verweise auf "int" Literale haben, aber das ist anders als die Auflösung von "constexpr", wie ich es verstehe. – erip

6

Im Gegensatz zu const, die int gilt, Das Schlüsselwort constexpr wendet const direkt auf die Variable des Referenztyps int& an, die keine Auswirkung hat.

typedef int &int_ref; 

int main() { 
    int x = 1; 
    int &a = x;   // OK 
    int_ref b = x;  // OK, int_ref is 'int &' 
    const int &c = 1; // OK, reference to const int 
    const int_ref d = 1; // error: type of d is 'int &' 
         // qualifier on reference are being ignored 
} 

constexpr int &n und constexpr int_ref n ist die gleiche, während const int &n und const int_ref n der Qualifier unterscheidet.

Verwandte Themen