在使用unique_ptr
时遇到了一些问题并试图阅读来源,但会出现更多问题。
Deleter
中的模板参数unique_ptr<class Tp, class Deleter = default_delete<Tp>>
是一个模板以外的类,所以我想知道它是否使用了allocator::rebind
(讨论发现here)等一些技巧。但不,它必须有一个确切的operator()(pointer)
超载。
所以我转向STL源代码(在Ubuntu 14.04 gcc 4.8中)并发现嵌套的_Pointer
类是为某些类型特征定义的,但绝对与将Deleter
类型重新绑定为无关与指针类型兼容的东西。
// /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;
我不知道该课程应该做什么,但似乎Tp
参数可以被覆盖。为了测试它,我制作了一些像这样的奇怪代码
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;
}
我完全糊涂了。有人会解释
unique_ptr
的删除器类型?答案 0 :(得分:1)
规则说如果MyDeleter
具有嵌套类型pointer
,则使用该类型。否则std::unique_ptr<double, MyDeleter>
将使用由第一个参数组成的double*
。
您存储的指针必须与unique_ptr
的结果指针类型匹配,否则最终删除将是UB。
因此,在std::unique_ptr<double, MyDeleter> p(new double(0));
的第一种情况下,当删除者期望double*
时,您会尝试存储int*
。这将永远不会奏效,因此编译器捕获它是件好事。