class A {};
int main() {
A() = A();
return 0;
}
なぜこのコードはコンパイルされますか?代入演算子の左側に左辺値を置くべきであるというエラーがありますか? A()は左辺ですか? g ++ 4.7のバージョンA()= A() - それはなぜコンパイルされますか?
class A {};
int main() {
A() = A();
return 0;
}
なぜこのコードはコンパイルされますか?代入演算子の左側に左辺値を置くべきであるというエラーがありますか? A()は左辺ですか? g ++ 4.7のバージョンA()= A() - それはなぜコンパイルされますか?
組み込み型の場合は、組み込みの代入演算子には、左側にの左辺の変更が必要です。
しかし、これは組み込み演算子を使用していませんが、クラスによって暗黙的に宣言されているオーバーロードです。これは
A().operator=(A());
とメンバ関数に相当する、メンバ関数である右辺値で呼び出すことができます。
あなたが本当にしたい場合、あなたはそれがC++ 11でコンパイルされないことができます。
class A {
template <typename T>
void operator=(T&&) && = delete; // no op= for rvalues
// generate other special members normally
A() = default;
A(A const&) = default;
A(A&&) = default;
~A() = default;
// op= only for lvalues
A& operator=(A&&) & = default;
A& operator=(A const&) & = default;
};
int main() {
A() = A(); // error
return 0;
}
注&
と&&
の終わりに(REF-修飾子別名)さまざまなoperator=
フォームの宣言。これにより、それらの宣言がそれぞれ左辺値と右辺値に対して選択されます。しかし、rvalueバージョンは、過負荷解決によって選択されると、プログラムが削除されて不正な形になります。
ただし、デフォルトの生成演算子=にはref-qualifierはありません。つまり、lvaluesとrvaluesの両方で呼び出すことができます。だからA()
がrvalueであっても、問題のコードはコンパイルされます。
C++コンパイラは、すべてのクラスにデフォルトのコンストラクタを提供します。これは、コードに関して、 A()= A(); 名前のないオブジェクトでコンストラクタを呼び出すだけで、関数は構築されたオブジェクトへの参照を暗黙的に返します。それはそれだ...
これはA(A())を使用しないのですか? – stardust
コピー初期化ではありませんか? – stardust
@Named:その呼び出す 'operator =' on A –