将所有权从 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*)>
与 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()}};
}
这可以推广到任何删除器类型。
与 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()}};
}
这可以推广到任何删除器类型。