1. ホーム
  2. c++

[解決済み] std::functionの使用法と構文

2022-03-03 06:38:45

質問

を使用する必要があります。 std::function が、以下の構文の意味がわかりません。

std::function<void()> f_name = []() { FNAME(); };

を使う目的は何ですか? std::function ? 関数へのポインタを作るため?

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

std::function は、型消去オブジェクトです。 つまり、ある操作がどのように行われるかの詳細を消去し、それに対する統一された実行時インタフェースを提供します。 例えば std::function の場合、主な 1 の操作は、コピー/移動、破壊、および「呼び出し」である。 operator() -- は、「関数ライクコール演算子」である。

あまり難解でない英語では、次のような意味になります。 std::function には、呼び出す方法が関数ポインタのように動作する、ほとんどすべてのオブジェクトを含めることができます。

サポートするシグネチャは角括弧の中に入ります。 std::function<void()> は引数ゼロで何も返しません。 std::function< double( int, int ) > は2つの int を引数にとり double . 一般的には std::function は、引数リストから引数を変換でき、戻り値をその戻り値に変換できる関数のようなオブジェクトを格納することをサポートしています。

重要なのは std::function とラムダは、互換性はあるにせよ、異なる生き物です。

次の行は、ラムダです。 これはC++11の新しい構文で、単純な関数のようなオブジェクトを書く機能を追加したものだ。 () . このようなオブジェクトは、型消去して std::function 実行時のオーバーヘッドを犠牲にして。

[](){ code } は、特にシンプルなラムダである。 これに相当する。

struct some_anonymous_type {
  some_anonymous_type() {}
  void operator()const{
    code
  }
};

上記の単純な擬似関数型のインスタンスです。 上記のような実際のクラスは、実装で定義されたユニークな名前(多くの場合、ユーザー定義型が含むことのできないシンボルを含む)とともに、コンパイラによって発明されます(このようなクラスを発明せずに標準に従うことが可能かどうかは分かりませんが、私が知る限りすべてのコンパイラは実際にクラスを作成しています)。

完全なラムダ構文は次のようになる。

[ capture_list ]( argument_list )
-> return_type optional_mutable
{
  code
}

しかし、多くの部分は省略したり、空のままにしておくことができる。 capture_list は結果として得られる無名型のコンストラクタとそのメンバ変数に対応し、 argument_list は operator() また、return typeは戻り値の型である。 ラムダインスタンスのコンストラクタも、capture_listでインスタンスを生成すると、魔法のように呼び出されます。

[ capture_list ]( argument_list ) -> return_type { code }

は基本的に

struct some_anonymous_type {
  // capture_list turned into member variables
  some_anonymous_type( /* capture_list turned into arguments */ ):
    /* member variables initialized */
  {}
  return_type operator()( argument_list ) const {
    code
  }
};

の中にあることに注意してください。 c++20 のテンプレート引数がラムダに追加されましたが、これは上記ではカバーされていません。

[]<typename T>( std::vector<T> const& v ) { return v.size(); }


1 また、RTTIが格納され(typeid)、cast-back-to-original-type操作が含まれる。