下部にある元の質問を参照してください。
私はあなたが今言っていることを理解していると思います.メンバー関数ポインタの内部構造はコンパイラ/マシン固有であるため、私がしようとしていることは実際には不可能です. そのため、テストすると機能しますが、他のコンパイラ/マシンで機能するという保証はありません.
私が望むことについて別の方法はありますか?
テンプレート クラスとそのクラスの基本テンプレート クラスがあり、デリゲート クラスが呼び出されたときに呼び出す必要があるすべてのイベントの std::map を含むデリゲート クラスがあります。
マップが必要な理由は、同じメンバー関数 (メンバー関数を指すイベント) が複数回追加されないようにするためと、最初に使用されたオブジェクトとメンバー関数を使用してマップからイベントを削除できるようにするためです。イベント オブジェクトをインスタンス化します。
template <class T_arg1> struct EventBase1
{
public:
bool operator < (const EventBase1 &event1) const { return _key < event1._key; };
virtual void operator()(T_arg1 t1) const {};
std::pair<intptr_t, intptr_t> _key;
};
template <class T, class T_arg1> struct Event1: public EventBase1<T_arg1>
{
template <class T_arg1> friend class Delegate1;
typedef typename void (T::*Method)(T_arg1);
private:
Method _method;
T* _object;
public:
Event1(T* object, Method method): _object(object), _method(method)
{
_key = std::pair<intptr_t, intptr_t>(reinterpret_cast<intptr_t>(object), reinterpret_cast<intptr_t>( reinterpret_cast<void*&>(method)));
};
virtual void operator()(T_arg1 t1) const {
(_object->*_method)(t1);
};
};
template <class T_arg1> class Delegate1
{
public:
typedef typename EventBase1<T_arg1> T_event;
void operator += (T_event* observer)
{
assert(observer);
_observers[*observer] = observer;
};
void operator -= (const T_event &observer)
{
std::map<T_event, T_event*>::iterator i = _observers.find(observer);
if(i != _observers.end()) {
delete i->second;
_observers.erase(i);
}
};
void operator()(T_arg1 t1)
{
for(std::map<T_event, T_event*>::iterator i = _observers.begin(); i != _observers.end(); i++) {
(*(i->second))(t1);
}
};
private:
std::map<T_event, T_event*> _observers;
};
元の質問:
関数ポインタを に格納しstd::map
、次のようにマップのキーを生成しています: std::pair<int, int>( (int)((int*)object), (int)(static_cast<const void*>(&method)) )
.
method
は関数 (メソッド) ポインターでありobject
、メソッドのオブジェクトへのポインターです。
それは機能しますが、キーの 2 番目の部分を取得する方法が完全に正しくないという卑劣な疑いがあります。
私は関数ポインタを完全に理解したことがありませんが、関数のアドレスではなくポインタのアドレスを取得していると思います.コンパイラは私にこのようなことをさせません((int)(static_cast<const void*>(method)))
.
だから私の質問は、関数ポインタから一意のキーを取得するにはどうすればよいですか?同じメソッドを指す別の関数ポインタからキーを後で取得した場合も同じです。
前もってありがとう、マーティン