2017-09-28 6 views
1

メンバ関数のコールバックを処理するために、より新しいバージョンのC++でより良い選択であることをちょっと調べてください。 ご協力いただければ幸いです。メンバ関数コールバックのバインドまたはラムダC++ 14

template<class T> 
void addCallBack(void(T::*someFunc)(int), T* instance) { 
    func = std::bind(someFunc, instance, _1); 
} 
std::function<void(int)> func ; 

または

template<class T> 
void addCallBack(T* instance) { 
    func = [&instance](int x) { 
     instance->someFunc(x); 
    } 
} 
std::function<void(int)> func; 
+0

「より良い」と定義します。 – stark

+2

Lambdaは、パフォーマンスの面で(と私の意見では、明快さの点で)ほとんど「束縛」よりも優れています。 – 0x5453

+0

仕事、正しい方法、良いプログラミングの練習などのためにもっと適切です。私はC++でほとんどのことを行う方法が100種類あり、この場合正しい方法があるのか​​、それとも重要なのかを知りたいと思いますか? – user3220058

答えて

4

この:

template<class T> 
void addCallBack(T* instance) { 
    func = [&instance](int x) { 
     instance->someFunc(x); 
    } 
} 

はそうあなたが宙ぶらりんの参照で終わるaddCallBack()の終わりでスコープから外れており、参照によって引数instanceを捕捉しています。だから、間違いなくではなく、です。

やりたいことです:

func = [instance](int x){ instance->someFunc(x); } 

か、単に:

func = [=](int x){ instance->someFunc(x); } 

今すぐ機能的な違い&短剣があるように起こっていません。それとの間

func = std::bind(&T::someFunc, instance, std::placeholders::_1); 

が、ラムダは、通常、(それがこのケースでのように)読みやすく、かつインラインしやすく、かつ任意の複雑な物事のより可能であることを行っています。後者の2つはこの場合重要ではありませんが、基本的には常にラムダを好む理由があります。


&dagger;もちろん、someFuncがオーバーロードされた名前であれば、これは動作しません。これはlambdaを好む理由の1つです。これはいつもうまくいくでしょう。

+0

実用的な機能上の違いはありませんが、ラムダのように一意に保証されているわけではありませんが(実際には複雑ですが)、実際にはstd関数から注意してバインド式を抽出できます。機能的な違いはありません。正気のないコードベースでは実用的な違いはありません。 – Yakk

関連する問題