2
\$\begingroup\$

Using modern C++ feature template argument deduction for class templates and folding expressions it is possible to implement "multi" scope guard utility, which have right order of functor calls:

#include <utility>

template< std::size_t I, typename F >
struct wrapper { F f; };

template< std::size_t I, typename F >
constexpr
F &
get(wrapper< I, F > * sg) noexcept
{
    return sg->f;
}

template< typename index_sequence, typename ...F >
struct scope_guard_base;

template < std::size_t ...I, typename ...F >
struct scope_guard_base< std::index_sequence< I... >, F... >
    : wrapper< I, F >...
{
    using base = scope_guard_base;
    scope_guard_base(F &... f) : wrapper< I, F >{std::forward< F >(f)}... { ; }
    ~scope_guard_base() { (get< (sizeof...(I) - 1 - I) >(this)(), ...); }
};

template< typename ...F >
struct scope_guard
    : scope_guard_base< std::index_sequence_for< F... >, F... >
{
    scope_guard(F &&... f) : scope_guard::base(f...) { ; }
};

#include <iostream>

template< std::size_t I >
struct F
{

    F() { std::cout << I << std::endl; }

    void operator () () const { std::cout << I << std::endl; }

};

int main()
{
    F< 0 > const f{};
    scope_guard _{f, F< 1 >{}, F< 2 >{}};
}

Output:

0

1

2

2

1

0

Live example.

\$\endgroup\$
  • \$\begingroup\$ This has a deadlock bug. If you do multi-mutex locking you need to pay special attention to the order of locking the mutexes (usually by the address) to avoid deadlock. \$\endgroup\$ – ratchet freak Oct 10 '16 at 11:38
  • \$\begingroup\$ @ratchetfreak Can you get an explanation? Can't find information about RAII and multiple mutexes deadlock interference. \$\endgroup\$ – Orient Oct 10 '16 at 11:54
  • \$\begingroup\$ @ratchetfreak Curly brackets (list initialization) guarantees strict ordering, I sure. At every step. \$\endgroup\$ – Orient Oct 10 '16 at 11:59
  • \$\begingroup\$ one thread calls scope_guard _{&mut1, &mut2}; another calls scope_guard _{&mut2, &mut1}; this can result in deadlock when each thread gets just one mutex. \$\endgroup\$ – ratchet freak Oct 10 '16 at 12:06
  • \$\begingroup\$ @ratchetfreak How it possible? It is defenitely different code. It is not the bug. It's looks like programmer's mistake. \$\endgroup\$ – Orient Oct 10 '16 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.