18

この式T()は(標準による)右辺値を作成すると思います。ただし、次のコードはコンパイルされます(少なくともgcc4.0では)。

class T {};

int main()
{
    T() = T();
}

メンバー関数は一時的に呼び出すことができ、上記は最初のから作成された一時的な右辺値に対してoperator =を呼び出すだけなので、技術的にはこれが可能であることを私は知っていT()ます。

しかし、概念的には、これは右辺値に新しい値を割り当てるようなものです。これが許可される正当な理由はありますか?

編集:私がこれを奇妙だと思う理由は、組み込み型では厳密に禁止されていますが、ユーザー定義型では許可されているためです。たとえば、int(2) = int(3)これは「割り当ての無効な左辺値」であるため、コンパイルされません。

ですから、本当の問題は、このやや一貫性のない動作が理由で言語に組み込まれたのではないかということだと思います。それとも歴史的な理由でそこにありますか?(たとえば、右辺値式でconstメンバー関数のみを呼び出すことができるようにする方が概念的には適切ですが、既存のコードが破損する可能性があるため、これを行うことはできません。)

4

5 に答える 5

13

operator =これは、純粋に演算子のオーバーロードと、コンソールへの印刷、ミューテックスのロックなど、より凝ったことをするためにオーバーロードする可能性があるために許可されています。

于 2010-05-28T04:31:50.890 に答える
7

はい、新しい値を右辺値に割り当てています。より正確にはoperator =、右辺値でメンバー関数を呼び出しています。組み込みの代入演算子を使用していないのに、なぜこれが問題になると思いますか?operator =はクラスのメンバー関数であり、右辺値で呼び出すことができるという事実を含め、ほとんどの点でクラスの他のメンバー関数と同様です。

「右辺値であること」は、オブジェクトのプロパティではなく、式のプロパティであるという事実も考慮に入れる必要があります。T()式が右辺値に評価されるのは事実です。それでも、T()式が生成する一時オブジェクトはオブジェクトであり、左辺値としてもアクセスできます。たとえば、割り当ての結果に対して他のメンバー関数を呼び出すことができ、*thislvalueを介して一時オブジェクトの「新しい」(新しく割り当てられた)値を確認できます。

(T() = T()).some_member_function();

const-referenceをアタッチすることで一時的なものの存続期間を延長することもでき、const T& r = T() = T();透けて見えるr値はオブジェクトの「新しい」値になります。ヨハネスが彼のコメントで正しく指摘したように、これはそれを一時的なものに添付しません。

于 2010-05-28T04:36:31.000 に答える
5

operator=をC++0xの左辺値でのみ機能するように制限できます。

class T
{
public:
    T& operator=(const T&) & = default;
};
于 2010-05-28T07:38:15.743 に答える
4

1つのPOVからは一貫性がありませんが、一貫性があることを見落としています。1)intおよびその他の組み込み型はCの場合と同じように動作します。2)クラス型のoperator =は、他のメソッドがない場合と同じように動作します。さらに別の特別な場合が必要です。

Cの互換性は、C ++の開始以来高く評価されており、C ++がなければ、今日ここに存在することは間違いありません。そのため、その部分は一般的に良いことです。

2番目のポイントは控えめです。特別な大文字小文字の演算子=はナンセンスコードを「機能」させるのではありませんが、そもそもナンセンスコードを気にするのはなぜですか?ガベージイン、ガベージアウト。現在のルールは、私が今まで見た限りでは、無視できるコストで定義された意味(ここではUBは悪いでしょう)を与えています。

私の溺愛者を考えると、物事はさらに単純化されるので、int() = int()許可されます。C ++ 0xは、右辺値参照、値などを使用してその方向に進み始めます。

于 2010-05-28T07:05:10.503 に答える
4

これが、標準ライブラリのいくつかのクラスを実装できる理由です。たとえば考えてみてくださいstd::bitset<>::operator[]

// bit reference:
class reference {
  friend class bitset;
  reference();
public:
  ˜reference();
  reference& operator=(bool x);           // for b[i] = x;
  reference& operator=(const reference&); // for b[i] = b[j];
  bool operator˜() const; // flips the bit
  operator bool() const;  // for x = b[i];
  reference& flip();      // for b[i].flip();
};

reference operator[](size_t pos); // for b[i];

行う場合は bits[i] = true、クラスタイプの右辺値に値を正確に割り当てます。によって返されるプロキシは、operator[]整数に効率的にパックされたスペースであるビットにアクセスできます。

于 2010-05-28T17:57:26.030 に答える