總之,能取址的一定是左值,除位域和暫存器變數(即register變數,但最新的編譯器,如gcc,遇到**中對register變數使用&取址時,會自動轉換成普通變數,即register關鍵字被忽略了)以外,左值皆可取址,即能使用&取址運算子。
以下列表所有左值:
1. 變數,函式名,成員變數名,無論其型別,即使變數型別是右值引用,其名字構成的表示式仍是左值表示式。注意:
void setvalue(int&& value)
void transfervalue(int&& value)
void transfervalue(int&& value)
2. 函式呼叫或過載運算子表示式,其返回型別為左值引用。如std::cout << 1, str1 = str2, ++i等
// 返回左值引用
int& handlevalue(int& value)
3. 所有內建(即非過載)的賦值及復合賦值表示式,因為表示式實際返回的是左值引用。如a = b,a += b,a %= b。
4. 內建的前置自增和自減表示式,即++a,--a。注意:此處是前置,後置自增和自減為純右值。
5. 內建的間接定址表示式,即*p,因為&(*p) == p。
6. 內建的下標表示式,即a[n] 和 p[a],但陣列a必須是左值。
7. 物件成員表示式,即a.m,但m如果是成員列舉項(不是列舉變數)或者是非靜態成員函式(參見下面的未決成員函式呼叫),或者a為右值且m為非引用型別的非靜態資料成員,則a.m表示式為純右值。
public:
enum color ;
void fun()
static int svalue; // 靜態資料成員
int value = 0; // 非靜態資料成員
int& r = value; // 引用型別
};test gettest()
int main(int argc, const char * ar**)
8. 內建的指標成員表示式,即p->m,但m如何是成員列舉項(不是列舉變數)或者是非靜態成員函式(參見下面的未決成員函式呼叫),則p->m表示式為純右值。
9. 物件成員指標表示式,即a.*mp,a必須是左值,且mp是資料成員指標。
typedef int (test::*mp); // 資料成員指標
mp mp = &test::value;
test t;
t.*mp; // 左值
10. 內建的指標的成員指標表示式,即p->*mp,且mp是資料成員指標。
11. 內建的逗號表示式,即(a,b),且b為左值(內建的逗號表示式返回是最右邊的值)
12. 三元條件表示式,即 a ? b : c,至於其什麼情況為左值,詳見條件表達運算子,個人經驗是當b和c都是左值時,表示式才是左值,否則是右值(純右值或亡值)
13. 字串字面量,例如:"ant"
14. 轉換成左值引用型別的轉型表示式,例如static_cast(x)
15. 返回型別為函式右值引用的函式呼叫表示式或者過載的運算子表示式,如void (&&) () 為返回空引數空的函式右值引用。
16. 轉換為函式右值引用型別的轉型表示式,如static_cast(x)。
表示式 a.mf 與 p->mf,其中 mf 是非靜態成員函式,以及表示式 a.*pmf 與 p->*pmf,其中 pmf 是成員函式指標,被歸類為純右值表示式。但它們不能用來初始化引用,也不能作為實參,只能用來作為函式呼叫運算子的左運算元(即p.mf(args)),總之我理解的就是無法驗證它是右值,但是它就是右值
參考:加入我們:
c 之左值和右值
1,左值和右值 定義 左值與右值這兩概念是從 c 中傳承而來的,在 c 中,左值指的是既能夠出現在等號左邊也能出現在等號右邊的變數 或表示式 換句話說,就是表示記憶體中可以定址,可以給它賦值 const型別的變數例外 右值指的則是只能出現在等號右邊的變數 或表示式 表示可以知道它的值 例如常數 變數...
c 之左值引用和右值引用
一 左值與右值定義 左值與右值這兩概念是從 c 中傳承而來的,在 c 中,左值指的是既能夠出現在等號左邊也能出現在等號右邊的變數 或表示式 右值指的則是只能出現在等號右邊的變數 或表示式 在 c 語言中,通常來說有名字的變數就是左值 如上面例子中的 a,b 而由運算操作 加減乘除,函式呼叫返回值等 ...
C C 差異之左值右值
c與c 在語法細節上還是有一些差異的,雖然一般情況下可能這些差異不足以造成結果的區別,但有些 確實會有影響。這次,主要總結下左值右值的差異。在c中,很多左值運算子的結果都不再是左值,然而在c 中,只要邏輯上可行,左值運算子的結果仍然是左值。c 的這種方式,讓運算子表示式之間的靈活性更大。1 i,我們...