質問

私にとっては使用する必要があります 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(), 、戻り値の型は戻り値の型です。lambda インスタンスのコンストラクターは、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
  }
};

に注意してください テンプレート引数がラムダに追加されましたが、これについては上では説明していません。

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

1 さらに、RTTI が保存され (typeid)、元の型へのキャストバック操作が含まれます。

他のヒント

ラインをバラバラにしましょう:

std :: function

これは、パラメーターを使用せず、値を返さない関数の宣言です。関数が返された場合 int, 、次のようになります:

std::function<int()>

同様に、INTパラメーターもかかった場合:

std::function<int(int)>

あなたの主な混乱は次の部分だと思います。

[]() { FNAME(); };

[] 部分はaと呼ばれます キャプチャ条項. 。ここでは、Lambdaの宣言にローカルな変数を置き、利用可能になりたいと思っています 内部 ラムダ機能自体。これは「私は何も捕らえられたくない」と言っています。これがクラスの定義の範囲内であり、クラスをラムダで利用できるようにしたい場合は、次のようにするかもしれません。

[this]() { FNAME(); };

次の部分は、ラムダに渡されるパラメーターです。 通常の機能とまったく同じ. 。前述のように、 std::function<void()> パラメーターを使用しないメソッドを指す署名なので、これも空です。

残りの部分は、ラムダ自体の本体です。 FNAME.

もう一つの例

次の署名があったとしましょう。つまり、2つの数字を合計できるものです。

std::function<int(int, int)> sumFunc;

このように、ラムダを宣言することができます。

sumFunc = [](int a, int b) { return a + b; };

MSVCを使用しているかどうかはわかりませんが、とにかくLamda Expressionの構文へのリンクがあります。

http://msdn.microsoft.com/en-us/library/dd293603.aspx

キャプチャ(ステートフルラムダ)を備えたラムダスは、たとえ同じように見えても、ユニークなタイプを持っているため、互いに割り当てることはできません。キャプチャでラムダを保管して通過できるようにするために、使用できます」std :: function「ラムダ式によって構築された関数オブジェクトを保持するため。基本的に」std :: function「さまざまなコンテンツ構造を持つLambda関数をLambda関数オブジェクトに割り当てることができるようにするためです。

経験:

auto func = [](int a){
 cout << "a:" << a << endl;
};
func(40);
//
int x = 10;
func = [x](int a){ //ATTENTION(ERROR!): assigning a new structure to the same object
 cout << "x:" << x << ",a:" << a << endl;
};
func(2);

したがって、上記の使用法は正しくありません。ただし、「std :: function」で関数オブジェクトを定義する場合:

auto func = std::function<void(int)>{};
func = [](int a){
  cout << "a:" << a << endl;
};
func(40);
//
int x = 10;
func = [x](int a){ //CORRECT. because of std::function
  //...
}; 

int y = 11;
func = [x,y](int a){ //CORRECT
 //...
}; 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top