Pass-through constructor for std::optional argument

145 views Asked by At

Is there a way, idiomatically, to provide a constructor/conversion which takes a std::optional<T> and returns a std::optional<U>? For instance, ideally I would love some kind of syntax like

#include <optional>

struct MyInt { 
  explicit MyInt(int i_) : i{i_} {}
  // magic here?...
  int i;
};

int main()
{
  MyInt i1 = MyInt(1);
  std::optional<int> opt_i{};
  std::optional<MyInt> i2 = MyInt(opt_i);  // empty
  opt_i = 3;
  std::optional<MyInt> i3 = MyInt(opt_i);  // contains MyInt(3)
}

I believe this is not currently possible. What are my best options?

1

There are 1 answers

11
463035818_is_not_an_ai On BEST ANSWER

std::optional already provides the desired conversion via constructors (4) and (5) listed here https://en.cppreference.com/w/cpp/utility/optional/optional.

#include <optional>

struct MyInt { 
  explicit MyInt(int i_) : i{i_} {}
  // magic here?...
  int i;
};

int main()
{
  MyInt i1 = MyInt(1);
  std::optional<int> opt_i{};
  std::optional<MyInt> i2{opt_i};
  opt_i = 3;
  std::optional<MyInt> i3{opt_i};
}

Live Demo

I haven't seen before std::optional::transform that is suggested in the other answer. I suppose it would be needed when MyInt itself does not provide a conversion from int but you want to transform it anyhow.