簡體   English   中英

錯誤:從'int'類型的右值開始,無效初始化'int&'類型的非const引用

[英]error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’

錯誤的形式:

int &z = 12;

正確形式:

int y;
int &r = y;

問題
為什么第一個代碼錯了? 標題中錯誤的“ 含義 ”是什么?

C ++ 03 3.10 / 1說:“每個表達式都是左值或左值。” 重要的是要記住左值與右值是表達式的屬性,而不是對象的屬性。

Lvalues命名超出單個表達式的對象。 例如, obj*ptrptr[index]++x都是左值。

Rvalues是在他們生活的完整表達結束時蒸發的臨時值(“以分號”表示)。 例如, 1729x + ystd::string("meow")x++都是rvalues。

address-of運算符要求其“操作數應為左值”。 如果我們可以獲取一個表達式的地址,則表達式是左值,否則它是一個右值。

 &obj; //  valid
 &12;  //invalid
int &z = 12;

在右側,從積分文字12創建int類型的臨時對象,但臨時對象不能綁定到非const引用。 因此錯誤。 它與:

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

為什么要創建一個臨時的? 因為引用必須引用內存中的對象,並且對於存在的對象,必須首先創建它。 由於該對象未命名,因此它是一個臨時對象。 它沒有名字。 根據這個解釋,第二種情況很好,為什么變得非常清楚。

臨時對象可以綁定到const引用,這意味着,您可以這樣做:

const int &z = 12; //ok

C ++ 11和Rvalue參考:

為了完整起見,我想補充一點,C ++ 11引入了rvalue-reference,它可以綁定到臨時對象。 所以在C ++ 11中,你可以這樣寫:

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

請注意,有&& intead of & 還要注意,不再需要const ,即使z綁定的對象是由integral-literal 12創建的臨時對象。

由於C ++ 11引入了rvalue-reference ,因此int& now現在稱為lvalue-reference

12是一個編譯時常量,與int&引用的數據不同,它不能改變。 可以做的是

const int& z = 12;

非const和const引用綁定遵循不同的規則

這些是C ++語言的規則:

  • 由字面數字( 12 )組成的表達式是“rvalue”
  • 不允許使用rvalue創建非const引用: int &ri = 12; 是不正確的
  • 允許使用rvalue創建一個const引用:在這種情況下,編譯器會創建一個未命名的對象; 只要引用本身存在,該對象就會持久存在。

您必須了解這些是C ++規則。 他們就是。

很容易發明一種不同的語言,比如C ++',規則略有不同。 在C ++中,允許使用rvalue創建非const引用。 這里沒有任何不一致或不可能。

但它會允許程序員可能達不到他想要的一些有風險的代碼,而C ++設計者正確地決定避免這種風險。

引用是可以改變(lvalues)的東西的“隱藏指針”(非空)。 您無法將它們定義為常量。 它應該是一個“變量”的東西。

編輯::

我在想

int &x = y;

幾乎相當於

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

其中__px是一個新名稱, __px #define x只在包含x引用聲明的塊內部工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM