2011-10-22 78 views
11

有這樣的代碼:改變返回值

#include <iostream> 
#include <string> 

int returnnumber() { return 2; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    //std::cout << (returnnumber() += 2) << std::endl; error: lvalue required as left operand of assignment 

    return 0; 
} 

爲什麼是有可能改變的std :: string的返回值,但不是int?

回答

10

因爲std::string是一個類型,其定義的+=運算符作爲成員函數。

並且該標準允許您在rvalues上調用成員函數。

的是一個愚蠢的後果是,

struct S { int x; }; 
S foo() { return S(); } 

int main() 
{ 
    foo() = S(); // OK, uses member assignment operator. 
    foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
} 

編譯結果:

 
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 
Copyright 1988-2008 Comeau Computing. All rights reserved. 
MODE:strict errors C++ C++0x_extensions 

"ComeauTest.c", line 7: error: expression must be a modifiable lvalue 
     foo().x = 666; // !Nah, can't assign to rvalue of built-in type. 
    ^

1 error detected in the compilation of "ComeauTest.c". 

然而,編譯器不同(或用於不同)他們是如何嚴格執行這一微妙的規則,或如果有的話。

歡呼&心連心,

+0

好吧,但對於'int',運算符'+ ='也被定義。 – Vlad

+0

@downvoter:爲什麼? – Vlad

+0

@anonymous downvoter:請解釋你的downvote,以便其他人可以從你的洞察中受益,或忽略一些愚蠢的原因。 –

2

的內置類型必須是一個可修改左值而是一個函數的返回值始終是一個右值如果函數賦值運算符的左側不返回引用類型。

operator+=std::string的成員函數,您可以調用類類型的右值上的成員函數。

+0

我想知道,爲什麼這樣的不一致? – Vlad

+0

你的意思是「一個賦值操作符的左側?」 –

+0

@VaughnCato:是的,我做過。謝謝。 –

1

出於同樣的原因

std::string("siema") += "cze"; 

作品。

您正在構建一個新對象並將其應用於operator +=(其中std::string)。

嘗試此操作將無法正常工作,因爲您的函數返回rvalue。這將是這樣的:

2 += 2 

你可以圍繞玩具與此:

#include <iostream> 
#include <string> 

int& returnnumber() { int * k = new int; *k = 2; return *k; } 
std::string returntext() { return "siema"; } 

int main() { 

    std::cout << (returntext() += "cze") << std::endl; // siemacze 
    std::cout << (returnnumber() += 2) << std::endl; //no error 
    std::string("siema") += "cze"; 
    return 0; 
} 

但是,這將導致內存泄漏,所以不這樣做。這只是一個概念證明,返回lvalue將工作。

+0

嗨Luchian :)不'returntext'也返回一個右值? – Vlad

+0

Charles Bailey寫道:如果函數沒有返回引用類型,函數的返回值總是一個右值。然後returntext返回右值或左值? – scdmb

+0

我很困惑,關閉做一些閱讀:) –

0

returntext()返回std::string,可以在後面的階段修改+=operator。但是,雖然returnnumber()返回int,但函數本身返回2,這是由const int決定的,並且不可更改,這就是編譯器抱怨的原因。