
2012/9/4 Lorenzo Caminiti <lorcaminiti@gmail.com>:
On Mon, Sep 3, 2012 at 6:37 PM, Sergey Radionov <rsatom@gmail.com> wrote:
2012/9/4 Lorenzo Caminiti <lorcaminiti@gmail.com>:
On Mon, Sep 3, 2012 at 10:28 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
Sergey Radionov wrote:
https://github.com/RSATom/finally_execute/blob/master/finally _execute.h
based on http://www.drdobbs.com/cpp/generic-change-the-way- you-write-excepti/184403758?pgno=2
I know about http://sourceforge.net/projects/loki-lib/ but with boost::bind this can be much simpler: https://github.com/RSATom/finally_execute/blob/master/README
I've used this in many of my projects, and found it very usefull....
don't understand, why this simple solution does not contributed already to Boost by someone else... :)
I created a version, too, but the usage is much simpler.
Given the following:
FILE * const file(fopen("test", "r")); if (file) { // A }
Your usage, at A, is:
finally_execute _(make_fin_exec(boost::bind(fclose, file)));
Mine is:
scope_guard _(fclose, file);
As you can see, a little more complication in the component makes usage much simpler.
Boost.ScopeExit allows you to "execute *arbitrary* code when the enclosing scope exits". I don't see how you execute arbitrary code with the above. Yep, but in 90% of cases I just need call one function on scope exit,
OK if that's what you need but that's not the problem that ScopeExit is trying to solve to "call a function on scope exit".
and in this case ScopeExit will be too cumbersome. little example:
void foo() { FILE* f1 = fopen( "file1.bin", "rb"); if( !f1 ) return; finally_execute close_file1 = make_fin_exec( boost::bind(fclose, f1) );
FILE* f2 = fopen( "file2.bin", "rb"); if( !f2 ) return; finally_execute close_file1 = make_fin_exec( boost::bind(fclose, f4) );
FILE* f3 = fopen( "file3.bin", "rb"); if( !f3 ) return; finally_execute close_file1 = make_fin_exec( boost::bind(fclose, f4) );
FILE* f4 = fopen( "file4.bin", "rb"); if( !f4 ) return; finally_execute close_file1 = make_fin_exec( boost::bind(fclose, f4) ); }
how it will look with ScopeExit?
If you are willing to use macros (as ScopeExit does), maybe something like this:
#define EXIT_CLOSE(f) \ BOOST_SCOPE_EXIT(&f) { \ fclose(f); \ } BOOST_SCOPE_EXIT_END
void foo() { FILE* f1 = fopen( "file1.bin", "rb"); if( !f1 ) return; EXIT_CLOSE(f1)
FILE* f2 = fopen( "file2.bin", "rb"); if( !f2 ) return; EXIT_CLOSE(f2)
FILE* f3 = fopen( "file3.bin", "rb"); if( !f3 ) return; EXIT_CLOSE(f3)
FILE* f4 = fopen( "file4.bin", "rb"); if( !f4 ) return; EXIT_CLOSE(f4) }
what will be more clear?
That depends on your application domain, maybe your developer's tema, etc so it's your call. ok, let's use example more closer to real life:
bool MoveFile(const char* from, const char* to) { FILE* f1 = fopen( from, "rb"); if( !f1 ) return false; finally_execute close_file1 = make_fin_exec( boost::bind(fclose, f1) ); FILE* f2 = fopen( to, "wb"); if( !f2 ) return false; finally_execute close_file2 = make_fin_exec( boost::bind(fclose, f2) ); finally_execute remove_file1 = make_fin_exec( boost::bind(remove, from) ); finally_execute remove_file2 = make_fin_exec( boost::bind(remove, to) ); /*do real move*/ if( was_error ) { remove_file1.dismiss(); return false; } else { remove_file2.dismiss(); return true; } }