Jak*_*old 4 c++ templates function-pointers
我在这里已经看到了这个问题的许多变体,但是我仍然觉得我的具体情况有所不同。
我的目标是包装一个如下所示的C API:
TF_Buffer* buf = TF_AllocateBuffer();
// ...
TF_DeleteBuffer(buf);
Run Code Online (Sandbox Code Playgroud)
由于我有许多这样的对象,因此我很想创建一个名为的通用类型handle,该类型可以容纳给定的指针,并在销毁时调用适当的释放器。我想象的用例是
class buffer : public handle<TF_Buffer, TF_DeleteBuffer> {
public:
buffer(TF_Buffer* b): handle(b) {}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,由于这TF_DeleteBuffer是一个简单的函数(类型void TF_DeleteBuffer(TF_Buffer*)),我无法使其正常工作。我确实设法通过为函数创建函数对象来解决此问题,因此以下内容确实有效
template<typename Obj, typename Deleter>
class handle {
public:
Obj* obj;
handle(Obj* o): obj(o) {};
~handle() { if (obj) Deleter()(obj); }
};
struct buffer_deleter {
void operator()(TF_Buffer* b) { TF_DeleteBuffer(b); }
};
class buffer : public handle<TF_Buffer, buffer_deleter> {
public:
buffer(TF_Buffer* b): handle(b) {}
}
Run Code Online (Sandbox Code Playgroud)
但是buffer_deleter仅为此目的而定义类感觉很脏。我想像这样的东西应该工作(带或不带std::function)
template<typename Obj, std::function<void(Obj*)> Deleter>
class handle {
// ...
}
Run Code Online (Sandbox Code Playgroud)
但我找不到使编译器满意的方法。据我了解,这有点类似于std::unique_ptr接受删除器类型对象,与std::shared_ptr接受删除器函数指针并将其存储在共享对象中。我不介意显式存储指针(并使用额外的内存),但是与此同时,鉴于我将创建许多此类,我希望有某种方法使其在语法上更美观。我真的不想将删除器指针传递给正在创建的对象的每个实例,这就是为什么我试图将其隐藏在模板中。
您可以将非类型模板参数定义为函数指针。
template<typename Obj, void(*Deleter)(Obj*)>
class handle {
public:
Obj* obj;
handle(Obj* o): obj(o) {};
~handle() { if (obj) Deleter(obj); }
};
Run Code Online (Sandbox Code Playgroud)
并像这样使用
class buffer : public handle<TF_Buffer, &TF_DeleteBuffer> {
...
};
Run Code Online (Sandbox Code Playgroud)