Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ HDF5函数和智能析构函数-std::unique_ptr()_C++_Smart Pointers_Hdf5_Hdf - Fatal编程技术网

C++ HDF5函数和智能析构函数-std::unique_ptr()

C++ HDF5函数和智能析构函数-std::unique_ptr(),c++,smart-pointers,hdf5,hdf,C++,Smart Pointers,Hdf5,Hdf,许多HDF5函数的初始化如下 hid_t handler = DoSomething(someHandler); 用户必须手动释放此类操作保留的内存,方法如下: freeme(handler); 因此,使用malloc和/或new操作符也会带来同样的噩梦/问题 我想创建一些类似于unique\u ptr的东西来在销毁时处理这个问题但是,问题是每个不同的函数都有不同的释放函数 例如: hid_t attribType = H5Aget_type(attribHandler); 必须以自由的方

许多HDF5函数的初始化如下

hid_t handler = DoSomething(someHandler);
用户必须手动释放此类操作保留的内存,方法如下:

freeme(handler);
因此,使用
malloc
和/或
new
操作符也会带来同样的噩梦/问题

我想创建一些类似于
unique\u ptr
的东西来在销毁时处理这个问题但是,问题是每个不同的函数都有不同的释放函数

例如:

hid_t attribType = H5Aget_type(attribHandler);
必须以自由的方式释放

H5Tclose(attribType);
H5Aclose(attribHandler);
但是这个函数

attribHandler = H5Aopen(obj_id,"name",H5P_DEFAULT);
必须以自由的方式释放

H5Tclose(attribType);
H5Aclose(attribHandler);
因此,我需要编写一个类,它可以将
hid\u t
作为模板参数(这很简单),也可以将释放函数作为某种参数,并在销毁时调用它

实现这一目标的最佳方式是什么


更新

有人建议我对自定义删除程序使用
std::unique_ptr
,但这不起作用,因为
std::unique_ptr
需要一个指针

std::unique_ptr<hid_t,std::function<herr_t(hid_t)>> attribType(H5Aget_type(attribHandler), [](hid_t f) { return H5Tclose(f); });
std::unique_ptr attribType(H5Aget_type(attribHandler),[](hid_t f){返回H5Tclose(f);});
由于第二个参数lambda函数,这将创建一个编译错误。错误显示为(g++4.9):

错误:从'hid_t{aka int}'到'std::unique_ptr::pointer{aka int*}'[-fppermissive]的转换无效
std::unique_ptr attribType(H5Aget_type(attribHandler),[](hid_t f){return H5Tclose(f);});
^
发生此错误的原因是
std::unique_ptr
希望保留指向
hid_t
的指针,而不是
hid_t
对象


有办法解决这个问题吗?我想我现在可以编写自己的类来实现这一点(我可以使用std::function来回答我的第一个问题),但如果我可以使用
std::unique\u ptr

以下内容可能会更好:

struct MyDeleter {
  typedef hid_t pointer;
  typedef void (*FreeFunc)(hid_t);
  FreeFunc free_func_;

  MyDeleter(FreeFunc free_func) : free_func_(free_func) {}
  void operator()(hid_t f) const { free_func_(f); }
};

std::unique_ptr<hid_t, MyDeleter> p(
    H5Aget_type(attribHandler),
    MyDeleter(H5Tclose));
struct MyDeleter{
typedef隐藏指针;
typedef void(*FreeFunc)(隐藏);
自由函数\u func;
MyDeleter(FreeFunc free_func):free_func(free_func){}
void运算符()(hid_t f)const{free_func_(f);}
};
std::唯一的\u ptr p(
H5Aget_类型(属性处理程序),
MyDeleter(H5Tclose));

我创建了自己的处理程序类。。。事实证明,这并不难:

template <typename T, typename Deleter>
class SmartHandle
{
public:
    typedef T value_type;
    typedef Deleter deleter_function;
private:
    T _value;
    Deleter _deleter;
public:
    SmartHandle(T value, Deleter deleter);
    ~SmartHandle();

    T get();
};

template <typename T, typename Deleter>
SmartHandle<T,Deleter>::SmartHandle(T value, Deleter deleter)
{
    this->_value   = value;
    this->_deleter = deleter;
}

template <typename T, typename Deleter>
T SmartHandle<T,Deleter>::get()
{
    return _value;
}

template <typename T, typename Deleter>
SmartHandle<T,Deleter>::~SmartHandle()
{
    _deleter(_value);
}
模板
类智能句柄
{
公众:
类型定义T值_类型;
typedef Deleter Deleter_函数;
私人:
T_值;
Deleter _Deleter;
公众:
智能手柄(T值,删除器删除器);
~SmartHandle();
T get();
};
模板
SmartHandle::SmartHandle(T值,Deleter-Deleter)
{
此->\u值=值;
此->\u deleter=deleter;
}
模板
T SmartHandle::get()
{
返回_值;
}
模板
SmartHandle::~SmartHandle()
{
_删除器(_值);
}
要使用它:

SmartHandle<hid_t,std::function<herr_t(hid_t)>> attribType(H5Aget_type(attribHandler.get()), [](hid_t f) { return H5Tclose(f); });
SmartHandle属性类型(H5Aget_类型(attribHandler.get()),[](hid_t f){return H5Tclose(f);});

这里的
attribHandler
也使用了
SmartHandle
,这就是为什么那里有一个
.get()

您可以使用类似于:

template <typename Factory, Factory factory,
          typename Deleter, Deleter deleter>
class SmartHandleH5;

template <typename Ret, typename ... Ts, Ret (*factory)(Ts...), 
          void (*deleter)(Ret)>
class SmartHandleH5<Ret (*)(Ts...), factory, void (*)(Ret), deleter>
{
public:
    template <typename ... Us>
    SmartHandle(Us&&... args) : handler(factory(std::forward<Us>(args)...)) {}

    // Not copyable
    SmartHandle(const SmartHandle&) = delete;
    SmartHandle& operator =(const SmartHandle&) = delete;

    // Not movable
    SmartHandle(SmartHandle&&) = delete;
    SmartHandle& operator =(SmartHandle&&) = delete;

    // To avoid strange case with our template constructor
    SmartHandle(SmartHandle&) = delete;
    SmartHandle(const SmartHandle&&) = delete;

    ~SmartHandle() { deleter(handler); }

    const T& get() const { return handler; }
    T& get() { return handler; }

private:
    Ret handler;
};
此外,您可能需要添加一个额外的层来完全隐藏
hid\u t

template <typename SmartHandle>
class HidHandle : private SmartHandle
{
public:
    using SmartHandle::SmartHandle;

    void foo() { someFunctionUsingHid(get()); }
};
模板
类HidHandle:私有SmartHandle
{
公众:
使用SmartHandle::SmartHandle;
void foo(){someFunctionUsingHid(get());}
};

使用HidHandleGetType=HidHandle;
使用HidHandleOpen=HidHandle;

std::unique\u ptr
将删除器作为额外的模板参数
std::shared_ptr
将删除器作为可选的额外构造函数参数。@IgorTandetnik噢!让我试试@IgorTandetnik请检查更新。“
std::unique\u ptr
需要一个指针”False
std::unique_ptr
Deleter::pointer
一起使用,它可能是
T*
。您需要投入更多的工作来创建一个合适的自定义删除程序。谢谢。。。但是我不得不说,编写自己的类要比这简单得多。其实我已经这么做了,因为我觉得你永远不会回应+1感谢您的帮助:-)您忘记删除复制构造函数和赋值(规则3)。@Jarod42您完全正确。这太快了,太脏了:)非常感谢你解决了这个问题(+1)。虽然您的解决方案非常完美,但我不喜欢使用多行来调用单个句柄。
template <typename SmartHandle>
class HidHandle : private SmartHandle
{
public:
    using SmartHandle::SmartHandle;

    void foo() { someFunctionUsingHid(get()); }
};
using HidHandleGetType = HidHandle<SmartHandlerGetType>;
using HidHandleOpen = HidHandle<SmartHandlerOpen>;