使用typedef为std::unique_ptr指定自定义默认删除器
Specifying custom default deleter for std::unique_ptr with typedef
我有一个C代码,与一些资源的工作。它有像
这样的函数ResourcePointer resource_new(void);
void resource_delete(ResourcePointer *res);
其中ResourcePointer
为
typedef void * ResourcePointer;
我想为std::unique_ptr
创建一个typedef
,指定自定义默认删除器。
下面的工作,但需要重复resource_delete
。
typedef std::unique_ptr<std::remove_pointer<ResourcePointer>::type,
void(*)(ResourcePointer)> Resource_auto_pointer;
和后面的代码
Resource_auto_pointer resource(resource_new(), resource_delete);
...
Resource_auto_pointer res2 = { resource_new(), resource_delete };
我应该如何改变typedef
,以便编译器每次需要时自动替换resource_delete
?我希望我的代码看起来像下面的
Resource_auto_pointer2 resource (resource_new());
...
Resource_auto_pointer2 res2 = { resource_new() };
编译器应该以某种方式猜测它应该为每个类型为Resource_auto_pointer2
的对象调用resource_delete
。
我在MS Visual Studio 2013中工作。
我读过其他类似问题的答案。有两件事我不明白。
- 为什么std::函数不工作?
- 为什么我要创建新的类型,既然(大概)一切都已经说了?
定义一个调用正确函数的函数对象:
struct resource_deleter
{
using pointer = std::remove_pointer<ResourcePointer>::type;
void operator()(ResourcePointer p) const { resource_delete(p); }
};
using res_ptr = std::unique_ptr<resource_deleter::pointer, resource_deleter>;
现在您不需要将deleter传递给unique_ptr
构造函数,因为deleter可以默认构造,并且会做正确的事情:
res_ptr p{ resource_new() };
在未求值的上下文中使用lambda,包括c++ 20 lambda:
#include <iostream>
#include <memory>
#include <type_traits>
using HANDLE = std::byte*;
HANDLE make_HANDLE() { static auto k_h = HANDLE{}; return ++k_h; } // AKA Win32's CreateFile etc
void close_HANDLE(HANDLE h) { std::cout << "HANDLE_close(" << h << ")" << std::endl; } // AKA Win32's CloseHandle etc
#if __cplusplus >= 202002 // C++20; using lambda in unevaluated context
using HANDLE_ptr = std::unique_ptr<
std::remove_pointer_t<HANDLE>,
decltype([](HANDLE h) { close_HANDLE(h); })>;
#else
[[maybe_unused]] inline static auto HANDLE_deleter = [](HANDLE h) { close_HANDLE(h); };
using HANDLE_ptr = std::unique_ptr<std::remove_pointer_t<HANDLE>, decltype(HANDLE_deleter)>;
#endif
int main()
{
auto h1 = HANDLE_ptr(make_HANDLE());
auto h2 = HANDLE_ptr(make_HANDLE());
auto h3 = HANDLE_ptr(make_HANDLE());
std::cout << h1 << std::endl;
std::cout << h2 << std::endl;
std::cout << h3 << std::endl;
}
我找到了我问题的答案。std::unique_ptr
需要实例化类型,而resource_delete
函数的地址是常量。需要创建struct
或class
来将其转换为type
相关文章:
- 没有默认构造函数作为模板参数的自定义比较器
- boost::p rogram_options 自定义验证和默认值
- 在priority_queue中使用默认容器但自定义比较器
- 同一系统上的自定义和默认提升库
- 为什么<wstring>使用自定义 wcscmp 和 wmemcmp 比较器对向量进行排序比默认快得多?
- 使用没有默认构造函数的类/类型初始化自定义容器
- 为什么我的自定义分配器比默认分配器慢
- 在C 中的自定义类的hashmap中的默认值
- 如何在自定义信号处理程序中以编程方式获取sigterm的默认行为
- 对于自定义类的一个未定义集,是否有一个默认的散列函数
- 自定义分配器和默认成员
- 如何在C++中使用默认和自定义复制构造函数
- 使用默认 cl.exe 或自定义蝙蝠进行构建
- STL 映射自定义键类 [默认构造函数]
- "Ctrl + F6"的默认处理在自定义 MDI 应用程序中不起作用
- 使用提升singleton_pool自定义分配比默认值慢
- 继承类使用非默认构造函数初始化自定义类
- 为什么自定义数据的 thrust::sort 需要一个默认的构造器,而 STL::sort 不需要?
- 带有自定义散列函数(bstrt)的无序映射仅适用于默认构造函数(重复键)
- 使用typedef为std::unique_ptr指定自定义默认删除器