2016-10-31 11 views
0
1 class Foo{ 
2 
3 }; 
4 
5 Foo func1(){ 
6 Foo f; 
7 return f; 
8 } 
9 
10 int func2(){ 
11 int a = 2; 
12 return a; 
13 } 
14 
15 int main(int argc, char** argv){ 
16 Foo var1; 
17 func1() = var1; //OK 
18 func2() = 1; //error: expression is not assignable 
19 return 0; 
20 } 

組み込み型の戻り値への代入は許可されていませんが、ユーザー定義型の戻り値への代入は許可されていますか?メモリはどのように管理されていますが、他は許されません。戻り値の範囲と代入

+1

func1()= var1;とはどういう意味ですか? –

+0

私はそれがFooクラスの代入演算子を呼び出すことを理解しています。私の質問は、この問題の組み込み型とユーザー定義型の根本的な違いは何ですか? Foo&演算子=(Foo&); – parsimons

+0

..そして何? –

答えて

1

値のカテゴリについてはthis articleをご覧ください。タイプと値のカテゴリ:

値カテゴリ

各C++式(等オペランド、リテラル、変数名とオペレータ)は、2つの独立した性質によって特徴付けられます。

[...]

  • 関数呼び出しまたは非基準リターンのオーバーロード演算子式:prvalue

    は、以下の式がprvalue式である[...]

    str.substr(1,2)のようなタイプ。

OKですので、式func1()func2()はprvaluesです。

[...]

右辺値

右辺値式はprvalueかはxValueのいずれかです。

ここで、prvaluesはrvaluesであることがわかります。

プロパティ:

[...]

右辺は、組み込み割り当て又は複合代入演算子の左側のオペランドとして使用することができません。ここで

[...]

は重要な部分です。このルールでは、組み込みの割り当てのみが除外されています。クラス型の代入演算子は引き続き使用できます。

組み込み演算子とクラス型演算子の違いは、言語の規則によって扱われる点が異なります。は、ビルトインタイプのために割り当て許可されていない理由を


は今、あなたは、を不思議に思われるかもしれませんか?まあ、それのためのユースケースはありません。代入には副作用がなく(左辺オペランドの値を変更する以外に)、戻り値は破棄されます。あなたがそれを書いたら、間違いを犯した可能性が最も高いです。それを許可しないことは、プログラマーにとって有益です。

今、あなたはrvalueクラス型にも役に立たないと思っているかもしれません。まあ、そうではないかもしれません!クラス型には、副作用を持つユーザー定義の代入演算子を使用できます。また、クラス型には、以前に実行された割り当てに応じて副作用を持つデストラクタを持つことができます。私はこれがBjarneまたは委員会が言語を指定した時に使用した理由であるとは保証できませんが、それは私の考えです。

+1

おそらく、自動的に合成された代入演算子は、左辺値にのみ適用されるように、 'operator =(const T &) &;')でなければならないでしょう(後に '&'があることに注意してください)。コンパイラが右辺値に代入されるように強制するには、演算子(const T&)&& = default;を書くことができます –

+1

@AaronMcDaidよく、 C++ 11の前には代入が存在していましたが、ref-qualifierはそうではなかったので、暗黙のコピー代入が最初にどのように指定されたのかは分かりませんでした。委員会の作業部会がそのような変更を時間の価値あるものと考えるかどうか - そのような変更が最初に公式に提案されていると仮定してください。 – user2079303

+1

欠点は、カスタムオーバーロードを持つ型の割り当てマジックを行うテンプレート。暗黙的な演算子を持つ型の割り当てを静かに最適化します。提案された変更は、そのようなテンプレートと後方互換性がありません。 – user2079303

関連する問題