0

この質問How to define a general member function pointerの受け入れられた回答から学んだ、コールバックのように機能するテンプレート クラスを作成することができました。

文字列に一致する適切なコールバックを呼び出せるように、文字列キーとコールバック値のマップが必要です。これは問題ありませんが、さまざまなクラスからのコールバックをサポートするマップが必要です。現在、1 つのクラスでのみ機能します。テンプレートのために任意のクラスにすることができますが、同じクラスからのコールバックのコレクションのみです。

class Apple {
public:
    void Red () {
        cout << "aa";
    }
};

class Orange {
public:
    void Blue () {
        cout << "bb";
    }
};

template <typename T>
class Callback {
    T *obj;
    void (T::*ptr) (void);

public:
    Callback (T *obj, void (T::*ptr) (void)) : obj (obj), ptr (ptr) {

    }

    void Call () {
        (obj->*ptr) ();
    }
};

こんな感じで使えます

Apple apple;
Orange orange;
Callback <Apple> callA (&apple, &Apple::Red);
Callback <Orange> callB (&orange, &Orange::Blue);
callA.call ();
callB.call ();

std::map <std::string, Callback <Apple>> appleCallbacks;

これができるようになりたい

std::map <std::string, Callback <anything>> anyCallbacks;

これを、同じ基本クラスを共有し、名前とそれが属するクラスを除いて定義が互いに同一である関数を持つクラスの束で使用する予定です。

class Base { };

class ChildA : public Base {
public:
    void Talk ();
}

class ChildB : public Base {
public:
    void Walk ();
}

したがって、これが機能する場合、 Talk () と Walk () の両方をマップに配置できます。

これはまったく可能ですか、それとも私の視点にはそもそも欠陥がありますか?

4

2 に答える 2

6

狂気は、このように嘘をつきます: コールバックを特定のクラスにバインドしないでください。代わりに、オブジェクトを使用しstd::function<Signature>て適切な関数オブジェクトを作成します。異なるクラスを操作する必要がある場合は、異なる型のオブジェクトも操作する必要があります。a を使用するstd::function<...>と、トリックを実行する必要があります。

std::map<std::string, std::function<void()>> operations;
operations["talk"] = std::bind(&ChildA::Talk, ChildA());
operations["walk"] = std::bind(&ChildB::Walk, ChildB());
operations["talk"]();
于 2013-10-04T23:21:53.990 に答える
4

ここでは継承の必要はありません。std::functionメンバー関数ポインターを格納し、メンバー関数ポインターstd::bindとオブジェクト インスタンスをバインドするために使用するだけです。

#include <functional>
#include <map>
#include <string>
#include <iostream>

struct Apple {
    void Red () {
        std::cout << "aa\n";
    }
};

struct Orange {
    void Blue () {
        std::cout << "bb\n";
    }
};

int main()
{
    std::map<std::string, std::function<void()>> m;
    Apple a;
    Orange o;

    m["apple"] = std::bind(&Apple::Red, a);
    m["orange"] = std::bind(&Orange::Blue, o);

    m["apple"]();
    m["orange"]();
}

出力:

aa
bb
于 2013-10-04T23:23:53.517 に答える