Got some questions when using the unique_ptr
and tried to read the source but more questions emerge.
The template parameter Deleter
in unique_ptr<class Tp, class Deleter = default_delete<Tp>>
is a class other than a template so I wonder if it uses some tricks like the allocator::rebind
(discussion found here). But no, it must have an exact operator()(pointer)
overload.
So I turned to the STL source (in Ubuntu 14.04 gcc 4.8) and find that a nested _Pointer
class is defined for some type traits, but absolutely nothing to do with rebinding the Deleter
type to something compatible with the pointer type.
// /usr/include/c++/4.8/bits/unique_ptr.h:112
class _Pointer
{
template<typename _Up>
static typename _Up::pointer __test(typename _Up::pointer*);
template<typename _Up>
static _Tp* __test(...);
// _Dp is the Deleter type
typedef typename remove_reference<_Dp>::type _Del;
public:
typedef decltype(__test<_Del>(0)) type;
};
// /usr/include/c++/4.8/bits/unique_ptr.h:130
// adopt the pointer type provided by the _Pointer
typedef typename _Pointer::type pointer;
I've no idea what that class is supposed to do but it seems the Tp
parameter can be overrided. To test it I've fabricated some weird codes like this
struct MyDeleter {
// in the deleter type, define the pointer as pointer to int
typedef int* pointer;
void operator()(pointer p)
{
delete p;
}
};
int main()
{
// this won't compile!
std::unique_ptr<double, MyDeleter> p(new double(0));
// this type is equivalent to std::unique_ptr<int, MyDeleter>
std::unique_ptr<double, MyDeleter> p(new int(0));
return 0;
}
I'm completely confused. Would anybody explain that
- Is there any approach to rebind the deleter type for
unique_ptr
? - Why is there such a mechanism to override the pointer type? Is that stated in the standard or just a "feature" in the gcc implementation?