将所有权从 unique_ptr<T,void(*)(T*)> 转移到 unique_ptr<const T,void(*)(const T*>

Transfer ownership from unique_ptr<T,void(*)(T*)> to unique_ptr<const T,void(*)(const T*)>

本文关键字:ptr gt const void lt unique 转移 所有权      更新时间:2023-10-16

有了reinterpret_cast,那将是这样的:

std::unique_ptr< const T , void (*) (const T *) >
to_const ( std::unique_ptr< T , void (*) (T *) > &ptr ) 
{ 
  return { ptr.release() , 
           reinterpret_cast< void (*) (const T *) >( ptr.get_deleter() ) } ; 
}

这里强制转换的删除器函数将使用对象调用,这实际上是非常量。
但是,有没有更清洁的方法可以在避免UB的同时进行这种转移?

不使用void (*)(const T *)作为删除器类型,不。但是我们可以制作自己的删除器:

template <class T>
struct ConstDeleter {
    void (*deleter)(T*);
    void operator()(T const* ptr) {
        deleter(const_cast<T*>(ptr));
    }
};
std::unique_ptr<T const, ConstDeleter<T>>
to_const(std::unique_ptr<T, void (*)(T*)>& ptr)
{ 
  return {ptr.release(), ConstDeleter<T>{ptr.get_deleter()}};
}

这可以推广到任何删除程序类型。