智能指针删除和“使用”关键字,名称为“指针”

时间:2015-04-27 12:04:26

标签: c++ smart-pointers

有时候我看到过这样的代码:

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:'初始化':无法从'initializer-list'转换   'std :: unique_ptr'没有构造函数可以获取源代码   类型或构造函数重载解析是不明确的

但是如果我取消注释行using pointer = void*;它就可以了!此外,如果我将别名更改为不同于pointer的名称,我会得到相同的错误。因此,使用具有确切名称using的{​​{1}}指令似乎至关重要。但为什么?我找不到任何解释。

2 个答案:

答案 0 :(得分:7)

您的unique_ptrT=int一起宣布。但是,constructors in std::unique_ptr不是T*,而是pointer参数。

pointer类型定义为

std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T*

当您未提供Deleter::pointer时,它最终为int*,当然无法从void*(来自Create)初始化。

答案 1 :(得分:2)

  

[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*的删除者。 / p>

你的删除器整体是否仍然严格有效,即使它是编译的,我也不想说。