
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