有时我看到这样的代码:
void* Create()
{
int* t{new int{10}};
return t;
}
class Deleter
{
//uncomment in order to compile
//using pointer = void*;
public:
void operator()(void* t)
{
delete t;
}
};
unique_ptr<int, Deleter> ptr{Create()};
它不编译。使用VS2013,它说:
错误:C2440:"正在初始化":无法从"初始值设定项列表"转换 到 'std::unique_ptr' 没有构造函数可以获取源代码 类型或构造函数重载分辨率不明确
但是如果我取消注释行using pointer = void*;
它就可以了!此外,如果我将别名更改为与pointer
不同的名称,则会出现相同的错误。因此,似乎拥有一个具有确切名称pointer
的using
指令至关重要。但是为什么?我找不到任何解释。
您的unique_ptr
声明T=int
.然而,std::unique_ptr
中的构造函数不接受T*
,而是pointer
参数。
此pointer
类型定义为
std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T*
当你不提供Deleter::pointer
它最终会int*
,当然不能从void*
初始化(从Create
)。
[C++11: 20.7.1.2/3]
如果存在类型remove_reference<D>::type::pointer
,则unique_ptr<T, D>::pointer
应是remove_reference<D>::type::pointer
的同义词。否则unique_ptr<T, D>::pointer
应是T*
的同义词。unique_ptr<T, D>::pointer
类型应满足 NullablePointer (17.6.3.3) 的要求。
这里需要它,因为您没有operator()(int*)
- 您正在"黑客"使用它以允许使用operator()(void*)
,而不是通过让删除器假装它是void*
的删除器。
您的删除器作为一个整体是否即使在编译时仍然严格有效,我不想说。