How to use lambda as std::unique_ptr's Deleter?

  • A+
Category:Languages

Check following contrived program:

#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; } 

From std::function constructor manual, I think constructing std::function object may throw exception, even the ratio is very low:

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

But if using function pointer instead of std::function object:

template<typename T> using UniPtr = std::unique_ptr<T, void(*)(T*)>; 

I think after leaving the func() scope, the dealloc object should be freed, and it can't be referenced. Please correct me if I am wrong. So the only safe method I can come out is defining a global dealloc function:

void dealloc(int* p) {     delete p; } 

But I don't like this method.

Based on precedent exposition, there is not 100% safe way to use lambda as std::unique_ptr's Deleter, Or I misunderstand something? How to use lambda as std::unique_ptr's Deleter?

 


I think after leaving the func() scope, the dealloc object should be freed, and it can't be referenced.

You don't need to worry about it. Yes the lambda object will be destroyed, but the pointer to function returned by the lambda's function pointer conversion function is always valid, it won't become dangled.

The value returned by this conversion function is a pointer to a function with C++ language linkage that, when invoked, has the same effect as invoking the closure object's function call operator directly.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: