Lambda Expression + RAII = The landscape of exception-safe programming will change in C++09!

Lambda Expression + RAII = The landscape of exception-safe programming will change in C++09!

Post by pongb » Tue, 25 Sep 2007 19:42:00


Exception-safe Programming is hard, but a scope(exit) facility like
that of D language can ease the task. Now it is difficult in C++03 to
implement a easy to use one ( http://www.yqcomputer.com/ ~nasonov/
scope_exit-0.04/libs/scope_exit/doc/html/index.html).

With C++09 coming, we can except that a much more elegant solution is
on the horizon!

Check the code below:

class ScopeExit
{
public:
ScopeExit(tr1::function<void()> func) : func_(func) { }
~ScopeExit() { func_(); }
private:
tr1::function<void()> func_;
};

#define BOOST_SCOPE_EXIT(expr) \
ScopeExit scope_exit_##__LINE__(expr)

// use case
void f()
{
bool commit = false;
account1.draw(10);
BOOST_SCOPE_EXIT((
<&>(){
if(!commit)
account1.deposit(10);
}
)); // lambda expression - see proposal N2413
account2.deposit(10);
commit = true;
}

Reference:
http://www.yqcomputer.com/

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Lambda Expression + RAII = The landscape of exception-safe programming will change in C++09!

Post by ymet » Tue, 25 Sep 2007 20:24:52


The cost of using tr1::function (to be std::function in C++09) can be
avoided:

template<class F>
class ScopeExit
{
public:
ScopeExit(F func) : func_(func) { }
~ScopeExit() { func_(); }
private:
F func_;
};

template<class F>
ScopeExit<F> make_ScopeExit(F func)
{
return ScopeExit<F>(func);
}

#define BOOST_SCOPE_EXIT(expr) \
auto scope_exit_##__LINE__(make_ScopeExit(expr))


Usage unchanged.

Yechezkel Mett

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]

 
 
 

Lambda Expression + RAII = The landscape of exception-safe programming will change in C++09!

Post by int19 » Thu, 27 Sep 2007 00:32:59


On a side note, curiously enough, this might be that rare case where
std::uncaught_exception is genuinely useful - it can only be true in
destructor of ScopeExit if the scope in which it was declared did not
complete normally. So:

class ScopeExitSuccess
{
public:
ScopeExitSuccess(tr1::function<void()> func) : func_(func) { }
~ScopeExitSuccess() { if (!std::uncaught_exception()) func_(); }
private:
tr1::function<void()> func_;
};

#define BOOST_SCOPE_EXIT_SUCCESS(expr) \
ScopeExitSuccess scope_exit_##__LINE__(expr)

void f()
{
account1.draw(10);
BOOST_SCOPE_EXIT_SUCCESS((<&>(){
account1.deposit(10);
}));
account2.deposit(10); // throws on failure
}

And then BOOST_SCOPE_EXIT_FAILURE defined similarly.
Also note that the original example was dangerous if deposit can throw
(since the second deposit could then throw from destructor).

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]