简体   繁体   English

为什么带有自定义删除器的unique_ptr对于nullptr不起作用,而shared_ptr呢?

[英]Why unique_ptr with custom deleter won't work for nullptr, while shared_ptr does?

Simple code to use either unique_ptr or shared_ptr as a scope guard. 使用unique_ptrshared_ptr作为范围保护的简单代码。 All information about what to clear is captured in the deleter , so I though it is safe to use nullptr for constructor. 有关清除内容的所有信息都在deleter捕获,因此我尽管将nullptr用于构造函数是安全的。

Apparently, with Visual C++ 2017 (14.1), it is not working as expected for unique_ptr , but works for shared_ptr . 显然,使用Visual C ++ 2017(14.1),它不能像unique_ptr那样工作,但适用于shared_ptr Is it a Microsoft quirk, or does the standard prevent calling the deleter of a unique_ptr when holding nullptr ? 这是微软的怪癖,还是标准阻止在持有nullptr时调用unique_ptrdeleter

In the code below, I'm forced to construct a unique_ptr with (void*)1 . 在下面的代码中,我被迫用(void*)1构造一个unique_ptr If I construct it with nullptr , cleaner won't be called. 如果我使用nullptr构造它,则不会调用cleaner For shared_ptr , there is no difference, cleaner is always called. 对于shared_ptr ,没有区别,总是调用cleaner

#include <memory>
#include <iostream>

int main()
{
    int ttt = 77;

    auto cleaner = [&ttt](void*) {
        std::cout << "cleaner: " << ttt << "\n"; // do something with capture here instead of print
    };

    std::unique_ptr<void, decltype(cleaner)> p((void*)1, cleaner);

    std::shared_ptr<void> q(nullptr, [&ttt](void*) {
        std::cout << "shared: " << ttt << "\n"; // do something with capture here instead of print
    });

    std::cout << "done\n";
    return 0;
}

unique_ptr 's destructor is required to do so: unique_ptr的析构函数需要这样做:

23.11.1.2.2 unique_ptr destructor [unique.ptr.single.dtor] 23.11.1.2.2 unique_ptr析构函数[unique.ptr.single.dtor]

2 Effects: If get() == nullptr there are no effects. 2效果:如果get() == nullptr没有效果。 Otherwise get_deleter()(get()) . 否则get_deleter()(get())

actually shared_ptr 's destructor is required to do the same: 实际上shared_ptr的析构函数需要执行相同的操作:

23.11.2.2.2 shared_ptr destructor [util.smartptr.shared.dest] 23.11.2.2.2 shared_ptr析构函数[util.smartptr.shared.dest]

— (1.1) If *this is empty or shares ownership with another shared_ptr instance ( use_count() > 1 ), there are no side effects. - (1.1)如果*this为空或与另一个shared_ptr实例共享所有权( use_count() > 1 ),则没有副作用。

— (1.2) Otherwise, if *this owns an object p and a deleter d, d(p) is called. - (1.2)否则,如果*this拥有对象p和删除器d,则调用d(p)。

So relying on smart pointers to perform arbitrary actions at scope exit while passing null pointers is not reliable. 所以依靠智能指针在传递空指针时在范围出口执行任意操作是不可靠的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 unique_ptr 将删除器作为类型参数而 shared_ptr 没有? - Why does unique_ptr have the deleter as a type parameter while shared_ptr doesn't? 将带有自定义删除器的unique_ptr移动到shared_ptr - Move a unique_ptr with custom deleter to a shared_ptr 为什么std :: shared_ptr <T> = std :: unique_ptr <T[]> 编译,而std :: shared_ptr <T[]> = std :: unique_ptr <T[]> 才不是? - Why does std::shared_ptr<T> = std::unique_ptr<T[]> compile, while std::shared_ptr<T[]> = std::unique_ptr<T[]> does not? 在shared_ptr的自定义删除器中检查nullptr是否有意义? - Does it make sense to check for nullptr in custom deleter of shared_ptr? Typedef带有静态自定义删除器的shared_ptr类型,类似于unique_ptr - Typedef a shared_ptr type with a static custom deleter, similar to unique_ptr 使用自定义删除程序为unique_ptr返回nullptr失败 - Returning nullptr for unique_ptr with custom deleter fails 使用 nullptr 初始化时从未调用过带有自定义删除器的 unique_ptr - Is a unique_ptr with custom deleter never invoked when initialized with nullptr std::unique_ptr 的自定义删除器如何工作? - How does the custom deleter of std::unique_ptr work? 为什么unique_ptr不会阻止自定义删除器的切片? - Why unique_ptr doesn't prevent slicing of custom deleter? Shared_ptr 自定义删除器 - Shared_ptr custom deleter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM