2011-10-22 1 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 ::文字列の戻り値を変更することは可能ですが、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". 

しかし、コンパイラが異なる(または異なるために使用される)彼らはこの微妙なルールを適用する方法を厳密について、またはもしあれば。

歓声& HTH。、

+0

'int'の場合、演算子' + = 'も同様に定義されています。 – Vlad

+0

@downvoter:なぜですか? – Vlad

+0

@anonymous downvoter:他人があなたの洞察力から恩恵を受けることができるように、または愚かな理由を無視して、あなたのdownvoteを説明してください。 –

2

ビルトインタイプが変更左辺値なければならないため、代入演算子の左側が、関数の戻り値は常に右辺で機能する場合参照型は返されません。

operator+=std::stringのメンバ関数であり、あなたは、クラス型の右辺値にメンバ関数を呼び出すことができます。同じ理由

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

作品については

+0

私は、なぜそんな不一致があるのだろうか? – Vlad

+0

「代入演算子の左辺ですか?」 –

+0

@VaughnCato:はい、しました。ありがとう。 –

1

新しいオブジェクトを作成し、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'もrvalueを返しませんか? – Vlad

+0

Charles Baileyが書いていますが、関数が参照型を返さない場合、関数の戻り値は常にrvalueです。 returntextはrvalueまたはlvalueを返しますか? – scdmb

+0

私は混乱しています。少し読んでおいて:) –

0

returntext()は、を返します。後の段階で変更することができます。+=operatorです。ただし、returnnumber()intを返しますが、関数自体は2を返しています。これは実際にはconst intであり、変更可能ではないため、コンパイラが苦情を言います。