
8 Aug
2015
8 Aug
'15
10:38 p.m.
Thank you Andrey, On 08/07/2015 11:07 AM, Andrey Semashev wrote: > On 07.08.2015 03:09, Marcel Ebmer wrote: >> ... >> https://github.com/maysl/BOOST_WITH > > I don't think this utility gives much compared to the naive macro-less > solution: > > f() { > { > Lock lock{the_mutex}); > do_something(); > do_other_thing(); > } > do_something_without_a_lock(); > } Your example nicely shows two things I want to overcome with 'with' 1) You define a variable that you never use 2) The solution, using an explicit scope, is not very expressive > > Also, your macro requires the type to be movable. This seems like a > rather strong requirement. For instance, it won't work with > lock_guard. If you really want to improve it you might want to use > 'for' statement instead of 'if', something along these lines: > I simply did not find a way to implement this for non-movable types (like lock_guard). Naturally, if there is one, I would be delighted! > template< typename T > > struct with_value > { > T value; > bool guard; > }; > > #define BOOST_WITH(x)\ > for (with_value<decltype(x)> w{x, true}; w.guard; w.guard=false) > The 'for' loop solution has a serious flaw in that you change the meaning of 'break' and 'continue': while (true) BOOST_WITH(whatever) // for(...) if (something) break; // breaks the single-pass for loop > There is another limitation that is not so easy to lift - you cannot > access the guard value from within the scope. For instance, you cannot > use the lock to block on a condition variable. > This limitation is 100% intentional. When I need access to the scoped variable, BOOST_WITH is not the way to go. The macro (or the hypothetical with-statement) is meant for the not so uncommon case where you do not care about the variable name. In fact, I originally had the idea because I had discovered this bug: void f() { std::lock_guard<std::mutex>{the_mutex}; // name missing, only a temporary do_something(); // the_mutex not locked } Marcel