ibse
ibse

Reputation: 583

Initialize boost::optional with ternary operator

Is the a way to initialize optional like:

bool conditional = true;
boost::optional<int> opt = conditional ? 5 : boost::none;

Why does the error occur?:

main.cpp:31:31: error: operands to ?: have different types ‘int’ and ‘const boost::none_t’
boost::make_optional(cond ? 5 : boost::none);
      |                          ~~~~~^~~~~~~~~~~~~~~~~

With simple if else I can do this:

boost::optional<int> opt;
if (cond)
    opt = 5;
else
    opt = boost::none;

Upvotes: 5

Views: 1613

Answers (3)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275385

?a:b requires that a and b have a common type to convert to that C++ can deduce.

boost::none and 5 don't have this.

auto opt = conditional ? boost::optional<int>(5) : boost::none;

that works

auto opt = conditional ? 5 : boost::optional<int>();

also works.

You can also write a helper

auto opt = maybe_optional( conditional, 5 );

where

template<class T>
boost::optional<T> maybe_optional( bool b, T t ) {
  if (b) return std::forward<T>(t);
  return boost::none;
}

Upvotes: 2

Niall
Niall

Reputation: 30605

The result of the of the ternary operator needs to be of a single type. The arguments, the left and right of the :, thus need to be of the same type, or convertible to the same type.

Upvotes: 1

ChrisMM
ChrisMM

Reputation: 10018

The ternary operator requires the left & right to be the same (or convertible) types. none_t and int aren't the same type. You can probably do cond ? boost::optional<int>(5) : boost:none

I don't use boost, so just guessing on syntax based on std::optional, but the following does work:

std::optional<int> opt = cond ? std::optional<int>(5) : std::nullopt;

Upvotes: 7

Related Questions