2

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?

5
  • 4
    You mean C++23 std::optional::transform? Commented Jan 23, 2024 at 7:42
  • @康桓瑋 Hmm, I guess that works but it's pretty ugly... auto i1 = std::optional<int>(); auto i2 = i1.transform([](auto&& i){return MyInt(std::forward<decltype(i)>(i));}); Commented Jan 23, 2024 at 7:55
  • 1
    But I guess no one has ever accused C++ of being pretty... Commented Jan 23, 2024 at 7:56
  • 2
    Correct me if I misunderstand something, but what's wrong with the bog standard std::optional constructor? std::optional<MyInt> i2{opt_i}; just works. Commented Jan 23, 2024 at 10:40
  • @n.m.couldbeanAI That is the best answer, yes. Unfortunately I simplified the question to the point of triviality. My second attempt is here. Commented Jan 23, 2024 at 18:07

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

11 Comments

Ah, I see... I simplified the example too much. This won't work for my actual example. Let me edit the question...
@kc9jud you should not edit hte question after receiving answers. This answers the question you did ask here. If you want to ask a different question you should open a new question.
@kc9jud well ok, I wouldnt mind too much. But note that invalidating answer that are already posted isnt nice. If you change your quesiton so that this answer doesnt apply anymore I can delete it and my effort is lost. Anyhow it was much more than a tiny edit on your code, so just go ahead. jsut dont forget to ping me, tahts the least you should do when your edit makes an answer not uptodate anymore
Should I just delete the question and ask a new one instead?
@kc9jud why would you delete the question?!?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.