2013-10-27 25 views
4
struct A {}; 

A f1() 
{ 
    return A(); 
} 

int f2() 
{ 
    return int(); 
} 

int main() 
{ 
    f1() = A(); // OK 
    f2() = int(); // error C2106: '=' : left operand must be l-value 
} 

爲什麼f1() = A();確定,而f2() = int();失敗?爲什麼int不能用作用戶定義類的返回值的l值?

+0

因爲設計師決定如此。 –

+2

從歷史上看,這是因爲左值表達式指定內存中的位置(「對象」),而右值表達式不(它們具有值)。有一個'int'值不是一個對象(沒有地址),但是沒有類型的值不是一個對象(因爲技術原因,我不完全確定,但除了別的什麼,這會是什麼?)。正如下面的答案所表明的那樣,術語從那裏變得更加複雜一些。 –

回答

2

函數f1返回一個右值,它可能會變成一個xvalue(一個「eXpiring」值)。函數f2返回一個內建類型,它是一個右值,它是一個前值(「純」右值)。

從3.10 [左值和右值]

— An xvalue (an 「eXpiring」 value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2).

因此,由於隱式移動操作A的分配變爲有效。

甲更改爲:

struct A { 
    A() {} 
    A(A&&) = delete; 
    A& operator = (const A&) { return *this; } 
}; 

生產:錯誤:使用刪除功能的 'A :: A(A & &)' 其中g ++(Ubuntu的/ Linaro的4.7.2-2ubuntu1)4.7.2

+0

在語句'return A();'中調用已刪除的構造函數,而不是在語句f1()= A();'按照[expr]/7(非必需註釋)中,沒有任何表達式這裏是一個xvalue。 [expr.call]/10顯式聲明「如果結果類型是左值引用類型或對函數 類型的右值引用,則函數調用是左值;如果結果類型是對對象類型的右值引用,則函數調用是x值;否則爲prvalue「。因此'f1()'和'f2()'產生一個前值。 – dyp

3

f1()返回A的實例。由於您沒有覆蓋複製/移動賦值操作符,編譯器會爲您生成一個。你基本上調用一個成員函數:

f1() = A(); // calls A& operator=(A&&) 

第二不起作用,因爲int是類類型的不是。

相關問題