如何唯一标识一个成员函数指针?

3
我正在为游戏引擎设置一个“类协程”系统,并且在模板函数中找不到任何唯一标识指向成员函数的方法,遇到了麻烦。
我想通过在基类中调用CoStart和CoStop方法并传递成员函数指针来启动和停止“行为”派生类中的协程。
CoStart( c_BlinkCycle );
CoStop( c_BlinkCycle );

协程方法具有标准签名,例如:

CoCommand MyBehavior::c_BlinkCycle( int step ) {
    // ...
}

我可以在基类中使用模板来很好地处理这些问题:

template<typename T>
void CoStart( CoCommand (T::* coMethod)(int) ) {
    // ...
}

然而,我希望能够在协程方法首次使用时(在CoStart()中)存储一些元数据,但不知道任何唯一标识它们的方式。例如:

if ( !metadataVector.contains( coMethod ) ) {
     // ... set up metadata
}

如果我能以某种方式获取指向成员函数的地址、类型 ID、名称或任何一种唯一标识符,那就好了。但是使用模板时,似乎没有任何共享指针类型可以将它们转换为,所以我有点不知所措。(FYI,我后来使用了 boost::function 和 boost::bind,但它们似乎也不允许比较)。

如果你有一个类 C,其中包含对象 c1c2,那么成员函数 C::someFunction() 对于对象 c1c2 是否应该相等?或者函数指针应该针对每个实例具体化? - Some programmer dude
不管哪种方式 - 如果它们相等,我可以通过“this”指针来区分。 主要挑战是区分C :: someFunction1()和C :: someFunction2()。 - QuadrupleA
你不能用<或>来比较它们,但我以为至少可以用==来比较成员函数的指针吧? - Nicholas Wilson
问题出在CoStart()函数的模板上 - 我想在Behavior基类中存储一个"CoCommand (T::* coMethod)(int)"以进行比较,但是T只存在于CoStart()的范围内。不过可以尝试将Behavior转换为Behavior<T>。[编辑:不幸的是,这样做行不通] - QuadrupleA
2个回答

0

你可以使用一个带有一些成员的对象来存储唯一标识它们的数据,而不是函数指针:

template <typename T>
class CycleMod { 
   public:
      CycleMod(Meta data): meta(data) { }
      CoCommand start(int){
      };
      CoCommand stop(int){
      };        
   private:
      MetaData meta;
};

你甚至可以使用类来包装指针,而不是使用成员函数。


不过并不想为每个协程创建对象。理想情况下,我只需在MyBehavior中定义一个c_BlinkCycle方法,然后调用CoStart(c_BlinkCycle)。 - QuadrupleA

0

好的,我想我要放弃尝试通过内在方式唯一地识别c_BlinkCycle()类型的方法(除非有人知道一个C++的技巧),而是让它们在获得特定的“步骤”参数时返回一个唯一的ID值:

CoCommand MyBehavior::c_BlinkCycle( int step ) {
    if ( step == -1 ) {
        return CoCommand_Identify(1);
    }

    // ... otherwise do the particular steps...
}

比我想象中有点啰嗦,但也不是世界末日。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接