Boost logo

Boost :

From: Alexander Nasonov (alnsn-boost_at_[hidden])
Date: 2005-11-10 14:55:07


Scott McMurray writes:
> Personally, I prefer the ScopeGuard-styled version. I have code that
> makes the following type of code work, if there's interest:
> int i = 2, j = 1;
> BOOST_FINALLY( std::cerr << ( boost::lambda::var(i) +
> boost::lambda::var(j) ) << '\n' );

How do you implement more complex finally block?

FILE* files[10] = {};

BOOST_FINALLY_BEGIN( (files) )
{
    for(int i = 0; i < 10; ++i)
        if(files[i])
            ::fclose(files[i]);
} BOOST_FINALLY_END

for(int i = 0; i < 10; ++i)
    files[i] = ::fopen(get_nth_filename(i), "r");

[skiped]
> Also, I think it would be best if your code wrapped the code in the
> destructor in a try block to eat all exceptions thrown. ( Although
> your version does allow the user to write his own try block around the
> code directly, so it's not totally necessary. Of course, this could be
> done in the ScopeGuard-style version as well by providing a functor
> adaptor that eats exceptions, were it decided that always having the
> try block is unacceptable. ) Personally, I think that the
> exception-eating version should be default, in the interest of safety.

I prefer not hiding catch(...) from a user.

BTW, I can modify the code to allow throw-spec before open brace

BOOST_FINALLY_BEGIN( (files) ) throw()
{
    for(int i = 0; i < 10; ++i)
        if(files[i])
            ::fclose(files[i]);
} BOOST_FINALLY_END

Also, there is also function-try-block in C++:

BOOST_FINALLY_BEGIN( (files) ) try
{
    for(int i = 0; i < 10; ++i)
        if(files[i])
            ::fclose(files[i]);
} catch(...) {} BOOST_FINALLY_END

--
Alexander

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