使用 void 指针从 c 函数调用模板化成员

Invoke a templated member from a c-function using void pointer

我的 C++ 代码必须与底层 C 库一起使用。我有一个看起来有点像这样的 C++ 对象:

template <typename T>
class MyClass
{
public:
  explicit MyClass(int x)
  : mVar(x)
  {
  }

private:
  int mVar;
};

稍后在我的 C++ 代码中,我执行以下操作:

  auto p = new MyClass<int>(10);

  call_c_lib_function((void*) p);

c 函数将指针 'p' 保存在一个更大的 c 结构中。后来当大 c 对象正在被销毁,它调用删除处理程序。

void
c_delete_handler(void* data)
{
  // data is holding the pointer value 'p' from above.
}

由于对象正在被销毁,我需要释放分配的对象。 根据 c++ 规范,'delete void_ptr' 未定义,因为它不知道如何 调用适当的析构函数。如何在适当的位置调用删除 模板对象?

我能想到的一个解决方案是围绕我的 MyClass 指针创建一个包装器结构。

struct Wrapper {
  enum template_type {
    template_int,
    template_double,
    template_string,
    ...
  };

  int template_type;
  void* obj_ptr;
};

在调用 call_c_lib_function 之前,我会执行以下操作:

  auto p = new MyClass<int>(10);
  auto w = new Wrapper()
  w.template_type = Wrapper::template_int;
  w.obj_ptr = (void*) p;

  call_c_lib_function((void) w);

现在在删除处理程序中,我可以执行以下操作:

void
c_delete_handler(void* data)
{
  Wrapper* w = (Wrapper*) data;

  switch (w->template_type) {
    case Wrapper::template_int:
      delete (MyClass<int>*) w->obj_ptr;
      break;

    case Wrapper::template_double:
      delete (MyClass<double>*) w->obj_ptr;
      break;
    ...
  }
}

这是正确的做法吗?有更好的选择吗? 将不胜感激任何意见。谢谢。

不使用 Wrapper,而是使用基数 class,如果可以的话。

class MyBase
{
   public:
      virtual ~MyBase() {};
};

template <typename T>
class MyClass : public MyBase
{
   public:
     explicit MyClass(int x) : mVar(x) {}

   private:
     int mVar;
};

然后

void c_delete_handler(void* data)
{
  Base* basePtr = reinterpret_cast<Base*>(data);
  delete basePtr;
}

这种方法避免了跟踪 MyClass 是否使用 intdoublestd::string 或 ....[=17= 实例化的需要]