1. ホーム
  2. c++

[解決済み] C++のデリゲートとは何ですか?

2022-04-23 09:30:55

質問

C++におけるデリゲートの一般的な考え方は?それらは何であり、どのように使用され、何のために使用されるのでしょうか?

まずは「ブラックボックス」的に勉強したいのですが、こういうもののガッツリした情報も少しあれば嬉しいです。

これは、最も純粋でクリーンなC++ではありませんが、私が働いているコードベースには、これらが豊富にあることに気づきました。私は、それらを十分に理解し、それらを使用することができ、恐ろしいネストされたテンプレートのひどさを掘り下げなくて済むようにしたいと思っています。

この2つの コードプロジェクト の記事は、私が言いたいことを説明してくれていますが、特に簡潔ではありません。

解決方法は?

C++でデリゲートを実現するには、信じられないほどの数の選択肢があります。以下は、私の頭に浮かんだものです。


選択肢1:ファンクタ。

を実装することで、関数オブジェクトを作成することができます。 operator()

struct Functor
{
     // Normal class/struct members

     int operator()(double d) // Arbitrary return types and parameter list
     {
          return (int) d + 1;
     }
};

// Use:
Functor f;
int i = f(3.14);


オプション 2: ラムダ式 ( C++11 のみ)

// Syntax is roughly: [capture](parameter list) -> return type {block}
// Some shortcuts exist
auto func = [](int i) -> double { return 2*i/1.15; };
double d = func(1);


オプション3:関数ポインタ

int f(double d) { ... }
typedef int (*MyFuncT) (double d);
MyFuncT fp = &f;
int a = fp(3.14);


オプション4:メンバ関数へのポインタ (最速の解決策)

参照 高速C++デレゲート コードプロジェクト ).

struct DelegateList
{
     int f1(double d) { }
     int f2(double d) { }
};

typedef int (DelegateList::* DelegateType)(double d);

DelegateType d = &DelegateList::f1;
DelegateList list;
int a = (list.*d)(3.14);


オプション5: std::関数

(または boost::function 標準ライブラリがサポートしていない場合)。速度は遅いですが、最も柔軟性があります。

#include <functional>
std::function<int(double)> f = [can be set to about anything in this answer]
// Usually more useful as a parameter to another functions


オプション 6: バインディング (使用 std::bind )

あらかじめパラメータを設定しておくことで、例えばメンバ関数を呼び出す際に便利です。

struct MyClass
{
    int DoStuff(double d); // actually a DoStuff(MyClass* this, double d)
};

std::function<int(double d)> f = std::bind(&MyClass::DoStuff, this, std::placeholders::_1);
// auto f = std::bind(...); in C++11


オプション7:テンプレート

引数リストと一致するものであれば、何でも受け入れる。

template <class FunctionT>
int DoSomething(FunctionT func)
{
    return func(3.14);
}