クラス タイプの右辺値参照への代入: 解決されたパラドックス
C の領域では、左辺値と右辺値の区別が最も重要です。左辺値は変更可能なメモリ位置を持つオブジェクトを表しますが、右辺値は変更できない一時オブジェクトまたは定数を具体化します。ただし、興味深いコード スニペットによって、この基本的な分割について疑問が生じます。
class Y {
public:
explicit Y(size_t num = 0) {}
};
int main() {
Y(1) = Y(0); // Here lies the enigma!
return 0;
}
なぜこのコードはコンパイルできるのでしょうか?コンストラクターによって返される右辺値は一時的であり、代入には適していませんか?
この矛盾を理解する鍵は、 C の暗黙的な代入演算子にあります。代入演算子がクラスに対して明示的に定義されていない場合、コンパイラはデフォルトの代入演算子を合成します。重要なのは、この合成演算子は場合によっては右辺値に適用できることです。
ここで明示的なキーワードが役割を果たします。この例では、Y クラスは代入演算子を宣言していないため、コンパイラが代入演算子を生成します。明示的なキーワードは、右辺値からの暗黙的な変換を防ぎますが、合成された代入演算子が右辺値に適用されることを妨げません。
したがって、コードでは、合成された代入演算子:
Y& Y::operator=(Y const&);
or
Y& Y::operator=(Y&);
は左側の右辺値 Y(1) で呼び出すことができます側。これにより、Y(1) が右辺値であっても代入を続行できます。
一時オブジェクトへの代入を防ぐために、参照修飾子 (&):
[ を使用して代入演算子を明示的に宣言できます。 &&&]class Y {
public:
explicit Y(std::size_t num = 0);
Y& operator=(Y const&) & = default;
};
この場合、代入演算子は合成されず、右辺値に代入しようとするとコンパイル エラーが発生します。 免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3