c++ - 如何在不使用 C++ 创建函数对象的情况下将函数指针作为模板值参数传递?
问题描述
我在这里看到了这个问题的许多变体,但我仍然觉得我的具体情况有所不同。
我的目标是包装一个如下所示的 C API:
TF_Buffer* buf = TF_AllocateBuffer();
// ...
TF_DeleteBuffer(buf);
由于我有很多这样的对象,我很想创建一个名为的泛型类型handle
,它可以保存给定的指针并在销毁时调用适当的释放器。我想象的用例是
class buffer : public handle<TF_Buffer, TF_DeleteBuffer> {
public:
buffer(TF_Buffer* b): handle(b) {}
}
不幸的是,我无法让它工作,因为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) {}
}
但是buffer_deleter
为了这个目的而定义类感觉很脏。我想像这样的东西应该可以工作(有或没有std::function
)
template<typename Obj, std::function<void(Obj*)> Deleter>
class handle {
// ...
}
但我找不到让编译器满意的方法。据我了解,这有点类似于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); }
};
并像使用它一样
class buffer : public handle<TF_Buffer, &TF_DeleteBuffer> {
...
};
推荐阅读
- sharepoint - MS Graph API:DriveItem 信息中的文件大小错误
- elasticsearch - Kibana 服务器未准备好 7.10
- logstash - 日期的 Logstash grok 模式
- xamarin - 在标签页子按钮单击上执行 A,在按下相同按钮 x 秒时执行 B
- c++ - 用 std::find_if 和 lambda 替换 for 循环
- sql - UidArray 的 TYPO3 9.5 Extbase 查询
- sql - SQL Self Join 并通过第三次连接的条件获取记录
- discord.js - 如何检查我的机器人具有哪些角色?[不和谐.js]
- javascript - 找到变量时返回
- java - 为什么 Android Studio 调试器不会停止在 runOnUiThread 内部调用的代码上