[英]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_ptr
或shared_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_ptr
的deleter
?
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
没有效果。 Otherwiseget_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 anothershared_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.