Boost logo

Boost :

Subject: [boost] Changes in Boost.Optional
From: Dean Michael Berris (dberris_at_[hidden])
Date: 2014-08-18 06:10:41


Suppose I have the following type:

struct container {
  boost::optional<uint16_t> optional() const {
    return value_;
  }
 private:
  boost::optional<uint16_t> value_;
};

struct value_wrapper {
  value_wrapper(const container& c) : c_(c) {}
  operator uint16_t () { return 1; }
  operator boost::optional<uint16_t>() { return c_.optional(); }
 private:
  const container& c_;
};

And that I have the following function:

value_wrapper value(const container& c) {
  return value_wrapper(c);
}

The following used to work in MSVC 2010:

container c;
// leave c.value_ alone.
boost::optional<uint16_t> some_value =
  value(c);
assert(!some_value);

Now with Boost 1.56, this breaks because the constructor for
some_value from a temporary optional is now marked explicit.

What is the work-around for the previous behavior to be regained? All
the following changes cause the assertion to fail:

boost::optional<uint16_t> some_value(value(c));
assert(!some_value); // some_value's constructor will use the
uint16_t conversion operator, therefore some_value == 1

boost::optional<uint16_t> some_value =
static_cast<boost::optional<uint16_t> >(value(c));
assert(!some_value); // same problem as above, the temporary created
will favor the uint16_t conversion operator

Help?

PS. For better context, see
https://github.com/cpp-netlib/cpp-netlib/blob/0.11-devel/boost/network/protocol/http/algorithms/linearize.hpp#L145


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk