如何使用lambda作为std :: unique_ptr的Deleter?

Nan*_*iao 6 c++ lambda smart-pointers unique-ptr c++11

检查以下人为的程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

std :: function构造函数手册,我认为构造std::function对象可能会抛出异常,即使比率非常低:

UniPtr<int> func()
{
    auto dealloc = [](int* p){delete p;};

    return UniPtr<int>{alloc(), dealloc};
}
Run Code Online (Sandbox Code Playgroud)

但是如果使用函数指针而不是std::function对象:

template<typename T>
using UniPtr = std::unique_ptr<T, void(*)(T*)>;
Run Code Online (Sandbox Code Playgroud)

我想在离开func()范围后,dealloc应该释放对象,并且不能引用它.如果我错了,请纠正我.所以我能找到的唯一安全方法就是定义一个全局dealloc函数:

void dealloc(int* p)
{
    delete p;
}
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这种方法.

基于先例论述,没有100%安全的方式可以lambda用作std :: unique_ptr的Deleter,或者我误解了什么?怎么lambda用作std::unique_ptr's Deleter

son*_*yao 5

我认为离开func()作用域后,该dealloc对象应该被释放,并且不能被引用。

你不需要担心它。是的,lambda 对象将被销毁,但lambda 函数指针转换函数返回的函数指针始终有效,不会成为悬空。

此转换函数返回的值是一个指向具有 C++ 语言链接的函数的指针,调用该函数时,与直接调用闭包对象的函数调用运算符具有相同的效果。