c++ - 如何将参数转发给模板成员函数到 C++ 中的成员基类指针

标签 c++ templates

我有一个 Foo 类,它使用 CRTP 从父类继承模板方法,避免提供大量单独的成员方法。像这样:

class Foo : public SomeBarClass<Foo>
{
//..
//from SomeBarClass
public:
    template <class T> void onMsg(T* msg);

private:
    IFoxMod* foxMod_;
};

现在,在 onMsg 的实现中,我想要这样的东西:

template <class T>
void Foo::onMsg(T* msg)
{
    if (foxMod_->shouldDoStuff(msg))
    {
        //do stuff
    }
}

并且可以有许多 foxMod_ 类型(其中一种在 Foo 构造函数中按配置文件中给定的名称实例化)只要它们遵守通用接口(interface)提供一个 bool shouldDoStuff 方法。问题是,这导致我定义以下内容:

struct IFoxMod
{
    virtual ~IFoxMod() {}
    template <class T> shouldDoStuff(T* msg) = 0;
};

对于要实现的所有 FoxMods(例如,class redMountainLogic : public IFoxMod 可能有它自己的辨别方式,当它适合做事情时)。

虽然这是非法的,因为不能有虚拟模板,我正试图找到一种解决方法。基本上,我需要动态调度,但我传递的参数是一个模板。我想不出解决方法。

最佳答案

虚函数表似乎与模板特化相处得不好。不足为奇。 VFT 通常基于声明顺序,这在模板中并不存在。一种解决方案是手动重新创建 VFT。

这是一个例子。它可能会更干净一些,但它确实有效。

#include<iostream>
using namespace std;

// Message.h

template<int n>
struct MessageByInt {
  typedef int Msg;
};

struct MessageOfHope {
  int a;
  int b;
  static const int id = 0;
};
template<> struct MessageByInt<MessageOfHope::id> { typedef MessageOfHope Msg; };

struct MessageOfDoom {
  int b;
  int c;
  static const int id = 1;
};
template<> struct MessageByInt<MessageOfDoom::id> { typedef MessageOfDoom Msg; };

const int nMessages = 2;

// IFoxMod.h

typedef bool(*callback)(void*);

struct IFoxMod {
  callback vtable[nMessages];
  template<typename MSG>
  bool ShouldDoWork(MSG* msg) {
    return vtable[MSG::id](msg);
  }
};

template<typename TESTER, int n>
struct filler {
  typedef typename MessageByInt<n>::Msg MSG;
  typedef typename TESTER::template Tester<MSG> Tester;
  static void fill(IFoxMod* impl) {
    impl->vtable[n] = reinterpret_cast<callback>(&Tester::ReallyShouldDoWork);
    filler<TESTER,n-1>::fill(impl);
  }
};

template<typename TESTER>
struct filler<TESTER,-1>{
  static void fill(IFoxMod* impl) {
  }
};

// RedFox.h

struct RedFoxTester {
  template<typename MSG>
  struct Tester { // This struct exists to allow partial specialization
    static bool ReallyShouldDoWork(MSG* msg) {
      return msg->b == 2;
    }
  };
};

struct RedFoxMod : public IFoxMod {
  RedFoxMod() {
    filler<RedFoxTester,nMessages-1>::fill(this);
  }
};

//Main

main() {
  IFoxMod* fm = new RedFoxMod();
  MessageOfHope mohb2 = {1, 2};
  MessageOfDoom modb2 = {2, 3};
  MessageOfHope mohbn2 = {2, 3};
  MessageOfDoom modbn2 = {1, 2};
  cout << fm->ShouldDoWork(&mohb2) << ", " << fm->ShouldDoWork(&modb2) << endl;
  cout << fm->ShouldDoWork(&mohbn2) << ", " << fm->ShouldDoWork(&modbn2) << endl;
}

关于c++ - 如何将参数转发给模板成员函数到 C++ 中的成员基类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14248153/

相关文章:

c++ - g++ 将字段的基本构造函数错误并忽略它的参数

c++ 模板和多态性没有合适的用户定义转换

c++ - 最大化调度具有依赖关系的单元任务的利润

c++ - macdeployqt 源的位置

c++ - 用于读取输入文件的内存映射文件有多安全?

c++ - 为什么我不使用这个就不能访问成员

django - 为什么将 Django 模板存储在其关联的应用程序中是不明智的?

c++ - std::enable_if_t = 0 的含义是什么

c++ - 文件系统父路径和 “..”字符串以返回到父路径

连接到 IPv4 地址时 C++ winsock 连接被拒绝