Why is boost::optional::is_initialized() deprecated?

Viewed 15624

I noticed today that boost::optional::is_initialized() is marked as deprecated in the Boost 1.64.0 reference. My projects are liberally sprinkled with is_initialized() to check if the boost::optional contains a value.

I don't see any other way to properly test if a boost::optional is initialized, am I missing something?

The boost::optional has a explicit operator bool(), meaning that I can do if(foo){...} if foo is a boost::optional. However, this would give wrong results if foo is a boost::optional<bool> or some other boost::optional<T> where T is convertible to bool.

What does Boost expect users to do?

3 Answers

As of this writing, Boost 1.72 supports a "has_value" method, which is not deprecated.

Under the hood, it just calls "is_initialized" though. See the code:

bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }

That aside, another convenient trick I've seen is the !! idiom. Eg:

boost::optional<Foo> x = ...
MY_ASSERT(!!x, "x must be set");

It's essentially the same as writing (bool)x or the even more prohibitively verbose static_cast<bool>(x).

Aside: it is a bit odd that is_initialized was deprecated, then an exactly equivalent function with a different name got added later. I suspect it was for compatibility with C++17's std::optional.

For future references, as stated on boost documentation, you can compare like this from now on:

boost::optional<int> oN = boost::none;
boost::optional<int> o0 = 0;
boost::optional<int> o1 = 1;

assert(oN != o0);
assert(o1 != oN);
assert(o0 != o1);
assert(oN == oN);
assert(o0 == o0);

You could even do:

if(oN != 2){}

or simply to check if the value is set:

if(oN){}

Related