【问题标题】:Way to uniquely identify a pointer-to-member-function?唯一标识指向成员函数的指针的方法?
【发布时间】:2012-12-14 23:31:10
【问题描述】:

我正在尝试为游戏引擎设置“类似协程”的系统,但在寻找任何方法来唯一标识模板函数中指向成员函数的指针时遇到了麻烦。

我希望能够通过调用基类中的 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、名称或任何类型的唯一标识符,我就会被设置。但是对于模板,我似乎没有任何可以将它们转换为的共享指针类型,所以我有点不知所措。 (仅供参考,我稍后会使用 boost::function 和 boost::bind ,但看起来它们也不允许比较)。

【问题讨论】:

  • 如果你有一个类C 和对象c1c2,成员函数C::someFunction() 是否应该对两个对象c1c2 相等,或者该函数应该指针特定于每个实例?
  • 两者都可以——如果它们比较相等,我可以通过“this”指针进行区分。主要挑战是区分 C::someFunction1() 和 C::someFunction2()。
  • 你不能用 比较它们,但我认为你至少可以用 == 比较指向成员函数的指针?
  • 问题在于 CoStart() 函数上的模板 - 我很想在 Behavior 基类中存储一个“CoCommand (T::* coMethod)(int)”以进行比较,但 T 只存在于 CoStart() 的范围内。可能会尝试将 Behavior 转换为 Behavior 。 [编辑:不幸的是,这行不通]

标签: c++ function-pointers


【解决方案1】:

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

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 )。
【解决方案2】:

好的,我想我将放弃尝试从本质上唯一地识别 c_BlinkCycle() 类型方法(除非有人知道 C++ 技巧),而是让他们在获得时返回一个 unqiue ID 值某些特殊的“步骤”参数:

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

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

比我想要的多一点样板,但不是世界末日。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多