C++11からC++でもラムダ式が使用できるようになったので、今更ですが使い勝手と、運搬性ををC#を比べてみました。ラムダ式を使用する方法と、変数に入れて持ち運ぶ方法の2とおりの使い方を確認しています。
C#でラムダを使用・運搬する
最初はC#です。かなり簡潔に書けます。これ以上の指定は存在しません。
public class CSharpClass { private flag; private Func<bool(int)> method; // 単純な呼び出し public Func<bool> GetLambda(int a) { return () => this.flag; } // ラムダへローカルメンバーを設定 public void SetLambda() { this.method = this.getFlag; // もしgetFlagがstaticメソッドだったら以下の通り // (クラス内ならクラス名修飾しなくてもよい) this.method = CSharpClass.getFlag; } private bool getFlag(int a) { return true; } }
C++でラムダを使用・運搬する
次はC++です。インスタンスメソッドの場合特別な指定が必要です。
class CppClass { bool flag; std::function<bool()> method; public: std::function<bool()> getFlag() { return [this]() { // VisualStudio2017だと->を入力しても // privateメンバーがインテリセンスに表示されない(?)けど // 普通にメンバー名を手打ちすれば使用可能 return this->flag; } } void SetLambda() { // フリー関数 this->method = getFlagFree; // クラスのメンバー関数 this->method = std::bind(&CppSample::getFlagLocal, this, std::placeholders::_1); // クラスのStatic関数を設定する場合 std::function<bool()> method = CppClass::methodByStatic; // ↑と意味は同じ(つまり無意味) this->method = std::bind(&CppSample::getFlagStatic, std::placeholders::_1); // こうするとthis->method(100)とかしても5で関数が呼ばれる this->method = std::bind(&CppSample::getFlagStatic, 5); } }
見ての通り、C++のほうが言語使用が多い&古いので使用がやや複雑です。が、今までの事を考えるとこれでもかなり進化していると見れます。
C#の方が指定が完結ですが、C++はbindを使用し、1層噛ましている形になるので、placeholdersの代わりに実数を指定して引数を固定する事ができます。ただし若干不可解な動きにはなりますが…