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?
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
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.
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;
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.
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
.
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