c++c++17stdoptional

Pass-through constructor for std::optional argument


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?


Solution

  • 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.