Frage

Kann mir jemand erklären, warum es einen Unterschied zwischen diesen beiden Aussagen gibt?

class A{};

const A& a = A();         // correct 

A& b = A();               // wrong

Es heißt ungültige Initialisierung der nicht konstanten Referenz des Typs A& von einem vorübergehenden Typ A

Warum tut const Materie hier?

War es hilfreich?

Lösung

Nicht-konstete Referenzen müssen mit L-Werten initialisiert werden. Wenn Sie sie mit Zeiträumen initialisieren könnten, was würde dann Folgendes tun?

int& foo = 5;
foo = 6; // ?!

const Referenzen haben die besondere Eigenschaft, dass sie die Lebensdauer des Schiedsrichters verlängern, und da sie es sind const, Es gibt keine Möglichkeit, dass Sie versuchen, etwas zu ändern, das nicht im Speicher sitzt. Zum Beispiel:

const int& foo = 5;
foo = 6; // not allowed, because foo is const.

Denken Sie daran, dass Referenzen sich tatsächlich auf etwas beziehen müssen, nicht nur vorübergehende Variablen. Zum Beispiel ist das Folgende gültig:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);

Andere Tipps

Die Terminologie dazu ist ein wenig verwirrend; Möglicherweise möchten Sie sie etwas weiter nachforschen. Hier ist jedoch die kurze Antwort:

Sie weisen einer Variablen ein temporäres Objekt (das Ergebnis des Aufrufens des Konstruktors der Klasse) zu. Ein temporäres Objekt ist ein R-Wert. Sie können einer nicht konstanten Referenz keinen R-Wert zuweisen.

Sie dürfen einer CONT-Referenz einen R-Wert zuweisen, obwohl die Begründung für die Zulassung ziemlich dunkel ist.

In C ++-Sprache ist es illegal, einen nicht konstanten Verweis an ein RValue beizubringen, während es perfekt in Ordnung ist, einen CONT-Verweis an einen RValue zu fügen. Zum Beispiel ist dies legal

const int& r = 5;

Während das nicht ist

int &r = 5; // ERROR

Ein temporäres Objekt vom Typ A zurückgegeben durch den Ausdruck A() Ist ein RValue, daher gilt die obige Regel auch in Ihrem Fall.

Für einen temporären/rensiver RValue können Sie nur eine CONT -Referenz haben.

Sie können einen nicht konstanten Verweis auf einen nicht-zeitgenössischen/lvalue haben.

A a;
A& b = a;

Ich glaube, der Grund, warum es ist, die Tatsache zu verstärken, dass ein RValue nur vorübergehend ist, da es wenig Wert gibt, etwas zu ändern, das momentan verschwinden wird.

Weil der Standard so sagt:

§8.5.3.5 ... Ansonsten muss die Referenz ein LVALUE-Verweis auf einen nichtflüchtigen konstanten Typ sein ...

Wenn Sie es jedoch sehr wollen, können Sie es bekommen:

#include <iostream>
int main()
{
  const int & cr=5;
  int & r=const_cast<int &>(cr);
  r=6;
  std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64

Aber seien Sie sich bewusst, dass die vermeintliche konstante CR auch nicht mehr konstant ist und Sie ein undefiniertes Verhalten entstehen. (§1.9 (4))

Wie aus dem obigen Code vorgeschlagen, gibt es keinen technischen Grund für den Unterschied. Vielmehr hatten die Designer Albträume darüber, was Benutzer mit nicht konstanten Hinweisen auf Zeiträume tun würden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top