Recently I tried to reinvent scope guard via 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 () (pointer 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;
}
Such an approach works fine for simple pointer to free function 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 an abundance of ... = pointer()
into the std::unique_ptr
definition (function default parameter, defaulting data memebers etc), but I can't find the DefaultConstructible requirement for pointer
into this article.
Is it mandatory, that the pointer
should match the std::is_default_constructible
requirement?
It tested against libc++
and against libstdc++
using not too old clang++ -std=gnu++1z
.
Seems, there should be language extension for lambdas: if auto l = [] {};
then using L = decltype(l)
is equivalent to struct L { constexpr void operator () () const noexcept { ; } }
, isn't it?
Aucun commentaire:
Enregistrer un commentaire