fout: ongeldige initialisatie van niet-const-referentie van het type ‘int&’ van een r-waarde van het type ‘int’

Onjuist formulier:

int &z = 12;

Correcte vorm:

int y;
int &r = y;

Vraag:
Waarom is de eerste code fout? Wat is de “betekenis” van de fout in de titel?


Antwoord 1, autoriteit 100%

C++03 3.10/1 zegt: “Elke expressie is ofwel een lvalue of een rvalue.” Het is belangrijk om te onthouden dat waarde versus waarde een eigenschap is van uitdrukkingen, niet van objecten.

Lwaarden geven een naam aan objecten die langer bestaan dan een enkele expressie. Bijvoorbeeld, obj, *ptr, ptr[index]en ++xzijn allemaal lwaarden.

R-waarden zijn tijdelijke waarden die verdampen aan het einde van de volledige expressie waarin ze leven (“aan de puntkomma”). Bijvoorbeeld, 1729, x + y, std::string("meow")en x++zijn alle rwaarden.

Het adres van de operator vereist dat zijn “operand een lwaarde is”. als we het adres van één uitdrukking zouden kunnen nemen, is de uitdrukking een lwaarde, anders is het een rwaarde.

&obj; //  valid
 &12;  //invalid

Antwoord 2, autoriteit 39%

int &z = 12;

Aan de rechterkant wordt een tijdelijk object van het type intgemaakt op basis van de integrale letterlijke 12, maar het tijdelijke object kan niet worden gebonden aan een niet-const-referentie. Vandaar de fout. Het is hetzelfde als:

int &z = int(12); //still same error

Waarom wordt er een tijdelijke aangemaakt? Omdat een verwijzing naar een object in het geheugen moet verwijzen, en om een object te laten bestaan, moet het eerst worden gemaakt. Aangezien het object geen naam heeft, is het een tijdelijkobject. Het heeft geen naam. Uit deze uitleg werd het vrijwel duidelijk waarom het tweede geval in orde is.

Een tijdelijk object kan worden gebonden aan een const-referentie, wat betekent dat u dit kunt doen:

const int &z = 12; //ok

C++11- en Rvalue-referentie:

Voor de volledigheid zou ik willen toevoegen dat C++11 rvalue-reference heeft geïntroduceerd, die kan binden aan een tijdelijk object. Dus in C++11 kun je dit schrijven:

int && z = 12; //C+11 only 

Merk op dat er &&is in plaats van &. Merk ook op dat constniet meer nodig is, ook al is het object waaraan zbindt een tijdelijkobject gemaakt uit integraal-letterlijke 12.

Sinds C++11 rvalue-referenceheeft geïntroduceerd, heet int&voortaan lvalue-reference.


Antwoord 3, autoriteit 7%

12is een constante tijdens het compileren die niet kan worden gewijzigd in tegenstelling tot de gegevens waarnaar wordt verwezen door int&. Wat u kuntdoen is

const int& z = 12;

Antwoord 4, autoriteit 4%

Niet-const- en const-referentiebinding volgen verschillende regels

Dit zijn de regels van de C++-taal:

  • een uitdrukking die bestaat uit een letterlijk getal (12) is een “rvalue”
  • het is niet toegestaan om een non-const referentie te maken met een rvalue: int &ri = 12;is slecht gevormd
  • het is toegestaan om een const-referentie te maken met een rwaarde: in dit geval wordt een naamloos object gemaakt door de compiler; dit object blijft bestaan zolang de referentie zelf bestaat.

Je moet begrijpen dat dit C++ regels zijn. Dat zijn ze gewoon.

Het is gemakkelijk om een andere taal uit te vinden, bijvoorbeeld C++’, met iets andere regels. In C++’ zou het toegestaan zijn om een non-const referentie te maken met een rvalue. Er is hier niets inconsistent of onmogelijk.

Maar het zou wat riskante code toestaan waar de programmeur misschien niet krijgt wat hij bedoelde, en C++-ontwerpers hebben terecht besloten dat risico te vermijden.


Antwoord 5

Verwijzingen zijn “verborgen verwijzingen” (niet-null) naar dingen die kunnen veranderen (lwaarden). Je kunt ze niet definiëren als een constante. Het zou iets “variabels” moeten zijn.

BEWERKEN::

Ik denk aan

int &x = y;

als bijna equivalent van

int* __px = &y;
#define x (*__px)

waar __pxeen nieuwe naam is, en de #define xwerkt alleen binnen het blok dat de declaratie van xreferentie bevat.

p>

Other episodes