2015-10-03 10 views
11

私は、カーネル関数への関数ポインタを持ち、外部から変更できるクラスを持っています。C++ラムダ - キャプチャメンバ変数

「提示された」動作を実現するにはどうすればよいですか?ラムダ内のクラス変数を読み込みます。私はfを内部に渡してそれをバイパスし、f.bar.iと書くことができますが、これはあまり良い解決策ではありません。

あなたがC++ 14を持っていない場合は何もないけれども、あなたが代わりに別の変数、

int &i = f.bar.i; 
f.kernel = [&i]() -> double { return i*i; }; 

を作成することができます

f.kernel = [&i = f.bar.i]() -> double { return i * i; }; 

、としてそれを書くことができますC++ 14では

+1

'[&f](){return f.i * f.i; } '? –

+0

@KerrekSB質問を編集しました –

+0

基本的には 'f.kernel()'を呼びたいし、 'kernel'はメンバ関数のように自動的に' f'にバインドする必要がありますか? – dhke

答えて

17

fを渡して、f.bar.iと書いてください。

+0

ニース。しかし、これはカーネルのラムダを 'f'のその特定のインスタンスにバインドします。そうではありませんか?したがって 'f2.kernel = f.kernel'を実行して' f2.kernel() 'を呼び出すと、' f'から 'i'を取得しますか?しかし、問題ではないかもしれません。 – dhke

+1

g ++ -std = C++ 11で最初の例をコンパイルしたFYIは、警告:-std = C++ 14または-std = gnu ++ 14でのみ使用可能な '警告:ラムダキャプチャイニシャライザ 'を提供するので、C++ 14の機能です – NathanOliver

+0

@NathanOliver "信じる"を削除しました。 @dhkeはい、 'f'から' f2'に 'kernel'をコピーすると、どちらのインスタンスからでも同じ関数を呼び出すことができます。 – aslg

7

you cannot do soと思われます。 メンバー関数lambdaを作成する構文はありません。

しかし、あなたはおそらくKerrekSBの提案@とその派遣に加え、まだメンバ関数を取得するための呼び出しに従うことができます:あなたは両方のフィールドkernelに名前を付けることはできません

class Foo 
{ 
public: 
    double kernel() 
    { 
     _kernel(*this); 
    } 

    std::function<double(Foo &)> _kernel; 
}; 


Foo f; 
f._kernel = [](Foo &f) -> double { return f.i * f.i; }; 
f.kernel() 

注意を。

+0

私はこの解決策も好きです。 '_kernel'をすべてのインスタンスが同じ"メンバ関数 "を共有するように静的にすることもできます。 – aslg

0

ラムダ関数は、iまたはBarについて認識しません。どうやって知ることができますか?参照を渡す必要があります。関数本体を別に定義して、iをパラメーターとして渡し、クラス内で呼び出すことができれば、必要なものを得ることができます。