【发布时间】:2019-02-10 02:09:23
【问题描述】:
检查以下人为程序:
#include <functional>
#include <memory>
template<typename T>
using UniPtr = std::unique_ptr<T, std::function<void(T*)>>;
int* alloc()
{
return new int;
}
UniPtr<int> func()
{
auto dealloc = [](int* p){delete p;};
return UniPtr<int>{alloc(), dealloc};
}
int main()
{
auto p = func();
return 0;
}
来自std::function constructor manual,我认为构造std::function对象可能会抛出异常,甚至比例很低:
UniPtr<int> func()
{
auto dealloc = [](int* p){delete p;};
return UniPtr<int>{alloc(), dealloc};
}
但是如果使用函数指针而不是std::function对象:
template<typename T>
using UniPtr = std::unique_ptr<T, void(*)(T*)>;
我认为离开func() 范围后,dealloc 对象应该被释放,并且它不能被引用。如果我错了,请纠正我。所以我能出来的唯一安全方法是定义一个全局dealloc函数:
void dealloc(int* p)
{
delete p;
}
但我不喜欢这种方法。
根据先例说明,将lambda 用作std::unique_ptr's Deleter 并不是100% 安全的方式,或者我误解了什么?如何将lambda用作std::unique_ptr的Deleter?
【问题讨论】:
-
你的意思是什么根据先例说明,没有100%安全的方式来使用lambda作为std::unique_ptr的Deleter?您指的是链接页面的哪一部分?
-
我不明白为什么
dealloc需要全局;如果您唯一担心的是它在func()退出后仍然可以引用,那么您不能只声明它static吗? -
@ruakh:你的意思是“
static auto dealloc = [](int* p){delete p;};”?是的,我以前无法提出这个想法,谢谢! -
@Praetorian 对不起,我糟糕的英语让你感到困惑。我的意思是构造
lambda到std::function对象可能会抛出异常。 -
@NanXiao 是的,确实可以。但大多数(可能是全部)
std::function实现使用小缓冲区优化来避免为小的可调用对象分配动态内存。无捕获的 lambda 几乎肯定会属于这一类。
标签: c++ c++11 lambda smart-pointers unique-ptr