error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'

Zła forma:

int &z = 12;

Prawidłowa forma:

int y;
int &r = y;

pytanie:
Dlaczego pierwszy kod jest zły? Co to jest" znaczenie " błędu w tytule?

Author: Aquarius_Girl, 2011-11-28

5 answers

C++03 3.10 / 1 mówi: "każde wyrażenie jest albo lvalue albo rvalue."Ważne jest, aby pamiętać, że wartościowość kontra wartościowość jest właściwością wyrażeń, a nie przedmiotów.

Lvalues nazywa obiekty, które utrzymują się poza pojedynczym wyrażeniem. Na przykład, obj , *ptr , ptr[index] , i {[4] } są wszystkie lvalues.

Rvalues to wartości czasowe, które wyparowują na końcu wyrazu pełnego, w którym żyją ("na średniku"). Na przykład, 1729 , x + y , std::string("meow") , oraz x++ są wartościami r.

Operator adresu wymaga, aby jego "operand był lvalue". jeśli możemy przyjąć adres jednego Wyrażenia, wyrażenie jest lvalue, w przeciwnym razie jest to rvalue.

 &obj; //  valid
 &12;  //invalid
 135
Author: BruceAdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 14:22:44
int &z = 12;

Po prawej stronie, tymczasowy obiekt typu int jest tworzony z całki literalnej 12, ale tymczasowy nie może być związany z referencją non-const. Stąd ten błąd. Jest to to samo co:

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

Dlaczego powstaje tymczasowy? Ponieważ odniesienie musi odnosić się do obiektu w pamięci, a aby obiekt istniał, musi być najpierw utworzone. Ponieważ obiekt jest nienazwany, jest to obiekt tymczasowy. Nie ma nazwy. Z tego wyjaśnienia, stało się to prawie jasne, dlaczego druga sprawa jest w porządku.

Obiekt tymczasowy może być powiązany z referencją const, co oznacza, że możesz to zrobić:

const int &z = 12; //ok

C++11 i rvalue Reference:

Dla kompletności chciałbym dodać, że C++11 wprowadził rvalue-reference, które może wiązać się z obiektem tymczasowym. Więc w C++11 możesz napisać to:

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

Zauważ, że istnieje && intad &. Zauważ również, że const nie jest już potrzebny, mimo że obiekt, który z wiąże się z tymczasowym obiektem utworzonym z całki-literalnej 12.

Ponieważ C++11 wprowadził rvalue-reference, int& obecnie nazywa się lvalue-reference.

 53
Author: Nawaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

12 jest stałą czasu kompilacji, której nie można zmienić w przeciwieństwie do danych, do których odwołuje się int&. Co tymożesz zrobić to

const int& z = 12;
 10
Author: Michael Krelin - hacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-28 08:55:05

Wiązania odniesienia Non-const i const są zgodne z różnymi zasadami

Oto zasady języka C++:

  • wyrażenie składające się z liczby literalnej (12) jest "rvalue"
  • nie jest dozwolone tworzenie odniesienia non-const z wartością R: int &ri = 12; is ill-formed
  • dozwolone jest tworzenie referencji const z wartością R: w tym przypadku kompilator tworzy nienazwany obiekt; obiekt ten będzie trwał tak długo, jak samo odniesienie istnieć.

Musisz zrozumieć, że są to Zasady C++. Po prostu są.

Łatwo jest wymyślić inny język, powiedzmy C++, z nieco innymi zasadami. W C++', dozwolone byłoby tworzenie odniesienia non-const z wartością r. Nie ma tu nic niespójnego lub niemożliwego.

Ale pozwoli to na ryzykowny kod, w którym programista może nie dostać tego, co zamierzał, a projektanci C++ słusznie zdecydowali się uniknąć tego ryzyka.

 5
Author: curiousguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-03 07:18:49

Odniesienia to "Ukryte wskaźniki" (inne niż null) Do Rzeczy, które mogą się zmieniać (lvalues). Nie można zdefiniować ich jako stałych. To powinno być coś "zmiennego".

EDIT::

Myślę o

int &x = y;

Jako prawie odpowiednik

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

Gdzie __px jest nową nazwą, a #define x działa tylko wewnątrz bloku zawierającego deklarację odniesienia x.

 0
Author: Basile Starynkevitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-28 09:21:20