Boost logo

Boost :

Subject: [boost] [scope_exit] capture list syntax for scope_exit and local_function
From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2009-01-14 06:55:03

gmane wrote:
> The following errors were found. Fix them, and submit again:
> You seem to be top-posting. Don't do that.
apparently gmane bug.

My current implementation uses ref/cref/val prefixes to pass arguments.
It's not consistent with C++0x lambda capture list syntax.

scope_exit: (ref a)(cref b)(val c)
c++0x: [&a, &b, c]

I have a proof-of-concept implementation for

BOOST_SCOPE_EXIT( (&a)(&b)(c) )
  std::cout << a << '\n' << b << '\n' << c << '\n';

It does not support passing by reference of classes with overloaded
unary operator& but they are rather rare and we can tell users to
use reference_wrapper to pass them.

Also, it does indirect function call. Gcc 3.4 and 4.2 don't optimize
it away even with -O3 but Intel 10.1 does (though, it generates a body
of the function even with -Os).

What do you think?

#include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/call_traits.hpp>
#include <boost/type_traits/is_function.hpp>

template<class T> inline T& deref(T* p, boost::false_type) { return *p; }
template<class T> inline T& deref(T& r, boost::true_type) { return r; }

void foo(int a, long const b, char const c)
  int &a_ref_test();
  int &b_ref_test();
  int c_ref_test();

  typedef boost::is_function<typeof(&a_ref_test)> is_not_ref_0;
  typedef boost::is_function<typeof(&b_ref_test)> is_not_ref_1;
  typedef boost::is_function<typeof( c_ref_test)> is_not_ref_2;

  typedef typeof(deref(&a, is_not_ref_0())) value_t_0;
  typedef typeof(deref(&b, is_not_ref_1())) value_t_1;
  typedef typeof(deref( c, is_not_ref_2())) value_t_2;

  typedef boost::mpl::if_<
>::type param_t_0;

  typedef boost::mpl::if_<
>::type param_t_1;

  typedef boost::mpl::if_<
>::type param_t_2;

  struct params_t {
    value_t_0 &a;
    value_t_1 &b;
    value_t_2 c;

    params_t(param_t_0 &a, param_t_1 &b, param_t_2 c)
      : a(a), b(b), c(c)

    void invoke(void (*f)(param_t_0 &a, param_t_1 &b, param_t_2 c))
      f( deref(&a, is_not_ref_0()),
         deref(&b, is_not_ref_1()),
         deref( c, is_not_ref_2())

  params_t params(
      deref(&a, is_not_ref_0()),
      deref(&b, is_not_ref_1()),
      deref( c, is_not_ref_2())
  void* p = ¶ms;

  struct guard_t {
    params_t* params;

    guard_t(void* p)
      : params((params_t*)p)


    static void body(param_t_0 &a, param_t_1 &b, param_t_2 c)
      std::cout << a << '\n' << b << '\n' << c << '\n';
  } guard(p);

int main()
  foo(0, 1, '2');


Boost list run by bdawes at, gregod at, cpdaniel at, john at