これは、このプラットフォームでの最初の質問です。不明な点や質問の仕方が適切でなかったら申し訳ありません。
以下のコードは、任意の C++11 コンパイラでコンパイルする必要があります。最小限に抑えてみました。このコードの意味は、この手順で失われる可能性がありますが、クラスと対応するメンバー関数のリストを保持して、それらすべてを同じパラメーターで呼び出すようにしようとしていることは明らかです。
#include <iostream>
class Base {
public:
virtual void Call(int x) = 0;
};
template<class T> class Extended : public Base
{
public:
// Constructor.
Extended(T* ptr, void (T::*memberFunction)(int)) : _ptr(ptr), _memberFunction(memberFunction) { }
// Call function.
void Call(int x) {
(_ptr->*_memberFunction)(x);
}
private:
// Pointer to class T.
T* _ptr;
// Function pointer.
void (T::*_memberFunction)(int);
};
class Test1 {
public:
void Fun1(int x) { std::cout << "Hello " << x << std::endl; }
};
class Test2 {
public:
void FunX(int x) { std::cout << (x * 2) << std::endl; }
};
class MyList {
public:
~MyList() {
for (auto it = _list.begin(); it != _list.end(); ++it) {
delete (*it);
}
}
template <class T> void Add(T* t, void (T::*memberFunction)(int)) {
_list.push_back(new Extended<T>(t, memberFunction));
}
void CallAll(int g) {
for (auto it = _list.begin(); it != _list.end(); ++it) {
(*it)->Call(g);
}
}
private:
std::list<Base*> _list;
};
int main() {
MyList myList;
Test1 test1;
Test2 test2;
myList.Add(&test1, &Test1::Fun1);
myList.Add(&test2, &Test2::FunX);
myList.CallAll(100);
}
これは完璧に機能します。私の問題は、リストからクラスとメンバー関数を削除する方法がわからないことです。さらに、同じクラスとメンバー関数が 2 回呼び出されることは望ましくありません。これは実質的に同じ問題です。Base 型の 2 つのクラスが等しいかどうかをチェックする必要があります。void ポインターを提供する仮想関数を提供できます。
virtual void* GetPtr() = 0;
しかし、それはクラスの同等性をチェックするだけです。このクラスの関数ポインターが等しいかどうかを確認する方法と、その方法がわかりません
template <class T> void MyList::Remove(T* t, void (T::*memberFunction)(int)) {
}
のように見える必要があります。
誰かが問題の解決策を知っていますか? それとも、このチェックはできませんか?
ジョー