6

当我创建一个unique_ptrwith 时deleter,它可以工作:

std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr(new Animal<Cat>, [](Animal<Cat> *ls) {
    delete ls;
});

但是,这段代码抛出错误:

std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr;
ptr = std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)>(new Animal<Cat>, [](Animal<Cat> *ls) {
    delete ls;
});

错误:

/usr/bin/../lib/c++/v1/memory:2561:13: error: static_assert failed "unique_ptr constructed with null function pointer deleter"
                static_assert(!is_pointer<deleter_type>::value,
                ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in instantiation of member function 'std::__1::unique_ptr<Animal<Cat>, void (*)(Animal<Cat> *)>::unique_ptr' requested here
            std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr;
                                                                ^

这是我的编译器版本:

Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix

Animal 和 Cat 类是微不足道的。这是整个代码

4

2 回答 2

11

显然不可能unique_ptr使用删除器的指针类型默认构造 a 。构造unique_ptr函数在 §20.7.1.2.1 [unique.ptr.single.ctor] 中有详细说明,其中包括:

constexpr unique_ptr() noexcept;

4备注:如果这个构造函数是用模板参数D[删除器类型]的指针类型或引用类型实例化的,则程序格式错误。

类似于您想要的符合标准的东西:

unique_ptr<int, void(*)(int*)> ptr{nullptr,[](int*p){delete p;}};
// ...
ptr.reset(new int(42));
于 2013-07-28T08:26:37.373 回答
11

在阅读了上面凯西的回答之后,我更改了我的代码以使用良好的旧 Functors 而不是 lambda 来使其工作。

这是我的解决方案:

struct Deleter {
    void operator()(Animal<Cat>* ls) {
        delete ls;
    }
};

int main() {
    std::unique_ptr<Animal<Cat>, Deleter> ptr;
    ptr = std::unique_ptr<Animal<Cat>, Deleter>(new Animal<Cat>);
    return 0;
}
于 2013-07-28T08:44:27.680 回答