4

次のコードを検討してください。

#include<utility>

struct S {
    void f(int) = delete;
    void f(int) && { }
};

int main() { }

もちろん、メンバーメソッドをオーバーロードできないと言ってコンパイルしません。もちろん、それは理にかなっています。

反対側では、次のコードがコンパイルされます。

#include<utility>

struct S {
    void f(int) & = delete;
    void f(int) && { }
};

int main() {
    S s;
    // s.f(42); <-- error, deleted member method
    std::move(s).f(42);
}

それは法規ですか?
同じクラス内で 2 つの完全に異なるインターフェイスを定義することは可能ではないでしょうか。前者は左辺値で使用され、後者は右辺値で使用されますか?
それがあまり意味をなさないという事実は別として、それは本当に私を傷つけます. 削除された関数は、左辺値の場合にのみ削除する
のではなく、全体として削除するべきではありませんか? この機能の目的は何ですか? それは古典的な目立たないコーナーケースですか、それとも私には見えない何かがありますか?

4

1 に答える 1

7

object がl -valueまたはr-value の場合、特定の操作を禁止することが理にかなっている場合があります。

の RAII ラッパーを想像してみてくださいFILE*。コンストラクタでファイルを開き、デストラクタで閉じて、手動制御を必要とする C 機能を C++ 例外セーフ クラスに変換します。C インターフェイスと対話するために、.get()生のポインターを返すメンバーがあります。誰かが書くかもしれません:

FILE* file = CFile("file.txt").get();

fileコンパイルされますが、間違っています。変数が初期化されると、ファイルはすぐに閉じられます。右辺値のオーバーロードを削除すると (そもそも提供しない)、コンパイル時エラーが発生し、バグハンティングから解放されます。

于 2016-02-13T22:52:56.167 に答える