
On 10/11/05, Alexander Nasonov <alnsn-boost@yandex.ru> wrote:
Is there an interest to write something like this
int i = 2, j = 1;
BOOST_FINALLY_BEGIN( (i)(j) ) { std::cerr << i + j << '\n'; } BOOST_FINALLY_END
in a code to make sure that a code inside finally block is always executed when leaving a scope?
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' ); The idea being that the macro simply expands to a line-number-dependant identifier of a ScopeGuard-style type ( http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm ) which, since it can never be dismissed, always calls the functor. The code itself is quite short, since it assumes that bind, lambda, or similar would be used to create the functor. With function<void(void)> it would be incredibly trivial, but, as described in the above article, the trick used avoids some otherwise-necessary virtual function calls. 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. Good compilers ought to remove them when they're obviously unnessesary anyways. Of course, the finally block is only really useful if the operation is nofail, but... - Scott McMurray