During preparation and presentation of a Lightning Talk about my BOOST_WITH Macro at the C++Now 2015 Conference, three important issues showed need for being addressed:

  1. The if statement solution with an unused (and useless) condition variable leads to compiler warnings. This is a noteworthy fail, since compiler warnings were part of my motivation for developing the macro in the first place!
  2. You could write code like
    BOOST_WITH(whatever) {} // if(true) {}
    else foo();

    – which is clearly not desirable.

  3. An alternative implementation, using a single-pass for loop suffers a similar problem – you could break and continue in a BOOST_WITH block.

The Macro clearly had to be revisited…

Using any kind of loop to achieve the desired scoping behavior was out of the question. In any case, break and continue would have been possible inside the with Block. A try-catch block would be an efficiency nightmare, and I could not think of any ways to abuse a switch statement, a lambda or whatever else.

So the if version had to be fixed. Here’s what I came up with: Use not the then-scope, but the else-scope! This enables us to cast the condition variable to void in the then-scope (problem 1 fixed), and it disables undesired composition with any trailing else (problem 2 fixed).


#include <utility>
#include <type_traits>

#define BOOST_WITH(what)                                                       \
    if (auto boost_with_intentionally_unused                                   \
        = boost::with_detail::make_false(what)) {                              \
        (void) boost_with_intentionally_unused;                                \
    } else

namespace boost {
namespace with_detail {

// wraps an object of movable type
// and makes it convertible to bool (always false)
template <class T>
class always_false {
    explicit always_false(T what) : x{std::move(what)} {}
    constexpr operator bool() const { return false; }

    T x;

// always_false<T> factory
template <class T>
auto make_false(T&& what, std::true_type) {
                  "this is a BOOST_WITH bug");
    return always_false<T>{std::forward<T>(what)};

// static error for non-movable types
template <class T>
auto make_false(T&&, std::false_type) {
                  "BOOST_WITH requires the scoped object's type to be move "
    return std::false_type{}; // never reached

// macro entry point, tag dispatch for static type checking
template <class T>
auto make_false(T&& what) {
    return make_false(std::forward<T>(what), std::is_move_constructible<T>{});
} // namepace boost::with_detail