智能指针删除器和"using"名称为"pointer"关键字

Smart pointer deleter and "using" keyword with a name "pointer"

本文关键字:pointer 关键字 using 删除 智能 指针      更新时间:2023-10-16

有时我看到这样的代码:

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不同的名称,则会出现相同的错误。因此,似乎拥有一个具有确切名称pointerusing指令至关重要。但是为什么?我找不到任何解释。

您的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*的删除器。

您的删除器作为一个整体是否即使在编译时仍然严格有效,我不想说。