
This should work with C++11:
template <typename T, typename F> void with(T &&t, F &&fn) { fn(std::forward<T>(t)); }
with(make_foo(), [](foo &&f) { // do things with foo. }); // foo is destroyed.
Don't think I can help w/r/t C++03 though, the lack of lambdas is a killer.
One thing this method doesn't do is automatically determine if the scope exit prematurely.
hmm... scanning your documentation do you mean the scope_completed flag? ok so if i understand correctly you're saying that foo could be a transaction, and when foo is destructed you either want to commit or rollback depending on whether or not the lambda succeeded? interesting... an easy thing to do is an overload of with for objects of T that has an on_exit method to expect a boolean lambda and call the on_exit callback with the result of the lambda. namespace detail { // for types that can handle failure template <typename T, typename F> void with_impl(T &&t, F &&fn, std::true_type) { auto value(std::forward<T>(t)); const auto scope_completed(fn(value)); value.on_exit(scope_completed); } // for other types template <typename T, typename F> void with_impl(T &&t, F &&fn, std::false_type) { fn(std::forward<T>(t)); } } // namespace detail template <typename T, typename F> void with(T &&t, F &&fn) { const auto has_on_exit(boost::hana::is_valid([](auto&& x) -> decltype(( void) x.on_exit(true)) { }); detail::with_impl(std::forward<T>(t), std::forward<F>(fn), has_on_exit); } quick disclaimer: written this all straight into gmail without running it. it'll almost certainly have an error or two in but the general idea is sound as far as i can tell. also i've used Boost.Hana for determining the existence of the field, this is obviously c++14 only, but i put it in here because it's so beautifully concise and doesn't get in the way of what the example is actually trying to show. this is still possible in c++11 too i just couldn't be bothered (nor know off by heart) all the boilerplate that comes with such a check. then this should work: struct transaction { void on_exit(bool scope_completed) { if (scope_completed) { db.commit(); } else { db.rollback(); } } // rest of class... }; with(make_transaction(), [](transaction &&t) { // returning on success of operation. return t.insert_1000_rows_concurrently(..); }); // t will commit/rollback depending on success of nasty insert method. an potentially better (and simpler!) alternative could be to (optionally) accept another lambda argument that is the on_exit callback and to call that instead of the class' member function. // prototype: with(T &&t, F &&fn, G &&on_exit); ditto for on_enter too if you want preconditions