2017-02-13 16 views
2

С reinterpret_cast, что будет что-то вроде:Передача права собственности от unique_ptr <T, ничтожной (*) (T *)> для unique_ptr <константный T, аннулируются (*) (константный T *)>

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()) } ; 
} 

Здесь функция casted deleter вызывается с объектом, который на самом деле не const.
Но есть ли более чистый способ сделать такую ​​передачу, избегая UB?

+0

Можете ли вы более четко форматировать свой код? – WhiZTiM

ответ

2

Не с 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()}}; 
} 

Это может быть обобщено на любой тип дебелтора.

+0

от имени const_cast я переписал самую ужасную часть моего довольно сложного (ужасного) каскада для размещения и построения объектов. пока я не могу придумать более чистый подход, спасибо. –