I recently tried to rethink area protection with std::unique_ptr ( NOTE : Deleter has a member of typedef pointer - this is a specially crafted case of std::unique_ptr ):
#include <type_traits> #include <utility> #include <memory> #include <iostream> #include <cstdlib> #include <cassert> namespace { template< typename lambda > auto make_scope_guard(lambda && _lambda) { struct lambda_caller { using pointer = std::decay_t< lambda >; void operator () (lambda & l) const noexcept { std::forward< lambda >(l)(); } }; return std::unique_ptr< std::decay_t< lambda >, lambda_caller >(std::forward< lambda >(_lambda)); } } int main() { std::cout << 1 << std::endl; { std::cout << 2 << std::endl; [[gnu::unused]] auto && guard_ = make_scope_guard([&] { std::cout << __PRETTY_FUNCTION__ << std::endl; }); std::cout << 3 << std::endl; } std::cout << 5 << std::endl; return EXIT_SUCCESS; }
This approach is great for a simple pointer to a free function void f() { std::cout << 4 << std::endl; } void f() { std::cout << 4 << std::endl; } passed to make_scope_guard , but not for any lambda passed to make_scope_guard .
This is due to the abundance of ... = pointer() in the definition of std::unique_ptr (default function parameter, default memebers data, etc.), but I cannot find the DefaultConstructible requirement for pointer in this article .
Is it mandatory that pointer must meet the requirement of std::is_default_constructible ?
It was tested against libc++ and against libstdc++ using the not-so-old clang++ -std=gnu++1z .
There seems to be a language extension for lambdas: if auto l = [/* possible capture list */] (Args...) { /* code */; }; auto l = [/* possible capture list */] (Args...) { /* code */; }; , then using L = decltype(l); equivalent to struct L { constexpr void operator () (Args...) const noexcept { ; } }; struct L { constexpr void operator () (Args...) const noexcept { ; } }; for some Args... right?
ADDITIONALLY:
Providing an instance of D{} following DefaultConstructible class for make_scope_guard(D{}) requires the comment code to be uncommented in the context of if (p) { ... , where p is of type D :
struct D { void operator () () const noexcept { std::cout << __PRETTY_FUNCTION__ << std::endl; } };
source share