【发布时间】:2018-10-16 12:54:00
【问题描述】:
使用unique_ptr 或shared_ptr 作为范围保护的简单代码。所有关于要清除的信息都在deleter 中捕获,所以我认为使用nullptr 作为构造函数是安全的。
显然,在 Visual C++ 2017 (14.1) 中,unique_ptr 无法正常工作,但shared_ptr 可以正常工作。这是微软的怪癖,还是标准阻止在持有nullptr 时调用unique_ptr 的deleter?
在下面的代码中,我不得不用(void*)1 构造一个unique_ptr。如果我用nullptr 构造它,cleaner 将不会被调用。对于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;
}
【问题讨论】:
-
@KillzoneKid 如我所说,请将
(void*)1替换为nullptr并重试。 -
不需要用
(void*)1构造一个无效的指针,用&p就行了。 -
可能值得一看 gsl::finally,它是 Guideline Support Library 的一部分,它正在实施来自 CppCoreGuidelines (Stroustrup & Sutter) 的建议。
-
@Barry:标准并不是这么说的。
shared_ptr默认构造函数将创建一个空的 shared_ptr。复制或移动一个空的 shared_ptr 也是如此,并且移动会使旧的 shared_ptr 为空。但它并不是说用nullptr构造会导致空的shared_ptr;相反,它保证use_count() == 1
标签: c++ c++11 visual-c++ language-lawyer