1. ホーム
  2. c++

[解決済み] C++11でstd::functionが空かどうかを適切にチェックする方法は?

2022-09-18 01:22:14

質問

を正しくチェックするにはどうしたらよいのでしょうか? std::function が空であるかどうかを適切にチェックする方法を知りたいのです。この例を考えてみましょう。

class Test {
    std::function<void(int a)> eventFunc;

    void registerEvent(std::function<void(int a)> e) {
        eventFunc = e;
    }

    void doSomething() {
        ...
        eventFunc(42);
    }
};

このコードはMSVCではうまくコンパイルできるのですが doSomething() を初期化せずに eventFunc を初期化しないと、コードは明らかにクラッシュします。それは予想できたことですが、私は eventFunc ? デバッガによると 'empty' . と表示されるので、簡単なif文を使って修正しました。

   void doSomething() {
        ...
        if (eventFunc) {
            eventFunc(42);
        }
   }

これは動作しますが、初期化されない std::function ? 私は、次のように書きたいのです。 if (eventFunc != nullptr) と書きたいところですが std::function は(明らかに)ポインタではありません。

なぜ純粋なifが動作するのでしょうか?その背後にある魔法は何ですか?そして、それをチェックする方法は正しいのでしょうか?

どのように解決するのですか?

ラムダが空であるかどうかではなく std::function に呼び出し可能なターゲットが格納されているかどうかをチェックしているのです。このチェックはよく定義されており、動作するのは std::function::operator bool への暗黙の変換を可能にする bool への暗黙の変換を可能にします。 if 文の条件式など)。

そのほかにも 空のラムダ という概念も、実は意味をなさない。裏側では、コンパイラはラムダ式を struct (または class ) の定義で、キャプチャした変数はこの struct . また、パブリックな関数呼び出し演算子も定義されており、これでラムダを呼び出すことができるようになっています。では、空のラムダはどうなるのでしょうか?


と書くこともできます。 if(eventFunc != nullptr) と書くことも可能です。 std::function は定義しています。 operator== そして operator!= との比較のためのオーバーロード。 nullptr_t .