Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::optional and type conversion

I was wondering if there is an elegant way to cast a boost::optional<A> to a boost::optional<B> when B can be constructed from A, albeit explicitely. This works:

# include <boost/optional.hpp>

class Foo
{
  int i_;
public:
  explicit Foo(int i) : i_(i) {}
};

int main()
{
  boost::optional<int> i;
  ... // i gets initialized or not
  boost::optional<Foo> foo;
  foo = boost::optional<Foo>(bool(i), Foo(i.value_or(0 /*unused value*/)));
  return 0;
}

but the need to put in there some value that will never be used seems awkward. Any better suggestion?

like image 850
P-Gn Avatar asked Feb 05 '15 15:02

P-Gn


1 Answers

template<class T, class U>
boost::optional<T> optional_cast( U&& u ) {
  if (u) return T(*std::forward<U>(u));
  else return {};
}

will amusingly also work with pointers.

int main() {
  boost::optional<int> i;
  ... // i gets initialized or not
  boost::optional<Foo> foo = optional_cast<Foo>(i);
  return 0;
}

In C++03

template<class T, class U>
boost::optional<T> optional_cast( U const& u ) {
  if (u) return T(*u);
  else return boost::none;
}

will work instead, but be less efficient in a number of cases.

like image 163
Yakk - Adam Nevraumont Avatar answered Oct 22 '22 19:10

Yakk - Adam Nevraumont