Boost logo

Boost :

From: Alexander Nasonov (alnsn_at_[hidden])
Date: 2007-08-22 04:48:12


Peder Holt <peder.holt <at> gmail.com> writes:

> I vote to accept BOOST_SCOPE_EXIT.
Thanks.

> The library complements scope guard in the same way as BOOST_FOREACH
> complements std::for_each. Both of them has a place, and it depends on
> the users preferences what they will use. I prefer BOOST_SCOPE_EXIT.

This is a good analogy, I like it.

> I would wish for a syntax more in line with BOOST_FOREACH (omitting
> the BOOST_SCOPE_EXIT_END, but the best I've been able to come up with
> is:
> {BOOST_SCOPE_EXIT( (commit)(m_persons) )
> {
> if(!commit)
> m_persons.pop_back();
> }
> };

Previous version of the library implemented the macro this way but it
looked too rubyish. In Ruby, a typical block look like this

{ |commit, m_persons|
        # Warning: next two lines are C++, not Ruby!
        if(!commit)
            m_persons.pop_back();
}

> With the leading open clause, this is not exactly an improvement...
>
> I too miss the BOOST_LOCAL_FUNCTION_DEF macro. This should be a part
> of the library before it is included in boost.

I would say, it should be a separate library that integrates nicely
with ScopeExit.

> One possible implementation is:
>
> ...
>
> which expands to:
> int i=5;
> int j=4;
> int (*function_ref)()=0;
> typedef BOOST_TYPEOF(i) type_0;
> typedef BOOST_TYPEOF(j) type_1;
> typedef BOOST_TYPEOF(function_ref()) return_type_1;
> struct name_impl {
> type_0& i;
> type_1& j;
> name_impl(type_0& i_,type_1& j_) : i(i_),j(j_) {}
> return_type_1 operator()(int x,int y)
> {
> i=x;j=y;
> return i+j;
> }
> } name(i,j);
> //...
>
> name(5,6);

There is one fundumental problem with this: name_impl is a local structure
and cannot be used in templates.

int result = accumulate(begin, end, 0, name); // Compilation error!

> When it comes to handle references or copies of arguments, I think the
> following can be made to work:
> int BOOST_LOCAL_FUNCTION_DEF(name,ref(i)const_ref(j)(k))(int x,int y)
> If not, the following can be made to work by using BOOST_PP_IS_UNARY.
> ( (const&)(i) ) ( j ), but this is starting to look like lisp.

'rref(i)const_ref(j)' looks good. I didn't think of const_ref before.

These names should be consistent with reference_wrapper helper
functions: ref and cref.

Passing by value can be either without any prefix (as you suggest) or
with the 'val' prefix.

--
Alexander

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk