2011-09-27 32 views
25

私はこれをどこからでも探していますが、私はまっすぐな答えを見つけることができないようです。いくつかの筋によれば、これは不可能だと言われていますが、それは私にとってより多くの質問を提起するだけです。C++ラムダ関数を渡す

だから状況はここにあります。 (これは単なる一例です)、私は以下のような選択機能を持つカスタムコンテナクラスがあるとします。

template <typename T> 
class Container { 
public: 
    // ... 

    Container<T> select(bool (*condition)(const T&)) const; 

    // ... 
}; 

だから、あなたが見ることができるように、select機能が条件関数へのポインタを取ります。これは、どの項目を選択すべきかを定義する関数です。したがって、この例の使用は、のようなもののようになります。

bool zero_selector(const int& element) { 
    return (element == 0); // Selects all elements that are zero 
} 

私はを充填した容器を持っている場合今、s = { 1, 1, 0, 0, 1, 0, 1, 0 }は言う、私は使用してゼロを含んでいるでしょうこれらのサブセットを選択できます。

t = s.select(&zero_selector); // t = { 0, 0, 0, 0 } 

ご覧のとおり、これはちょっと大変です。ラムダ関数は、例えば、そう、私は(私はこれはそれのために正しい構文であるかどうかわからないんだけど)を使用することができ、これははるかにエレガントになるだろう:

t = s.select([&] (int x) -> bool { return (x == 0); }); 

私の質問です、これは可能ですか?もしそうなら、私の関数プロトタイプはContainer::select()のためにラムダをそのパラメータの1つとして受け入れるべきでしょうか?

もし可能でないなら、引数の1つとしてラムダ式を使用できるstd::for_eachのようなものはどうですか?これをはっきりと説明するどんなリソースでも大いに感謝します。私が見つけたすべてのものは、ラムダ関数の例を示し、std::function<>をパラメータとして渡しますが、ラムダ関数ではstd::for_eachがどのように動作するかについては何も説明していません。

このコードは現状のままコンパイル/テストされていません。それはデモンストレーションの目的のみです。私は実際のプロジェクトで同じ原則を実装しようとしましたが、うまくいきません。

答えて

12

関数ポインタに変換できるように、ラムダをステートレス(つまり、キャプチャ仕様が空の場合[](int x)-> bool {...})として宣言する必要があります。

+6

か 'のstd :: function'を使用するか、選択し'ますあなたはおそらくているすべてのラムダがキャプチャか、転換され、std::functionを受け入れるように選択機能を宣言する必要があります、と述べた

'テンプレート – bdonlan

+0

あなたの解決策を試しました(上記の正確なコードで'& 'を削除してください)、それは動作しません。 '' anonymous-namespace ':: 'を 'bool(__cdecl *)(const T&)'に変換できないため、エラーC2664が返されます。 – Zeenobit

+1

@teedayf、それはC++ 11の新しいものです。 Visual Studio 2010はそれをまだサポートしていません。そして、ラムダを '[](const int&x){...}'として宣言して関数ポインタのシグネチャに一致させる必要があります。 – MSN

33

ニージャークを追加する必要はありません[&] - キャプチャ。

[] (int x) -> bool { return (x == 0); } 

Capturelessのラムダは、対応する関数ポインタに変換されているので、これは、箱から出して動作するはずです:あなたのラムダは、それを必要としません。

Container<T> select(std::function<bool(const T&)> predicate) const; 
関連する問題