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

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

前段时间看到这样一段代码:

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,它说:

error: C2440: 'initializing' : cannot convert from 'initializer-list' to 'std::unique_ptr' No constructor could take the source type, or constructor overload resolution was ambiguous

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

[C++11: 20.7.1.2/3] If the type remove_reference<D>::type::pointer exists, then unique_ptr<T, D>::pointer shall be a synonym for remove_reference<D>::type::pointer. Otherwise unique_ptr<T, D>::pointer shall be a synonym for T*. The type unique_ptr<T, D>::pointer shall satisfy the requirements of NullablePointer (17.6.3.3).

这里是必需的,因为你没有 operator()(int*) — 你在 "hacking" 附近,以允许使用 operator()(void*),而不是让删除器假装它是 [=19 的删除器=].

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

您的 unique_ptr 声明为 T=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)初始化。