3

I would like to understand better the difference between creating a boost::optional object using the default constructor:

boost::optional<PastaType> pasta = boost::optional<PastaType>(spaghetti)

or using the make_optional version:

boost::optional<PastaType> pasta = boost::make_optional<PastaType>(spaghetti)

Looking around I just understoood that with the make_optional version PastaType cannot be a reference type, but I would like to figure out better when to use one or the other.

Thanks!

giubacchio
  • 117
  • 1
  • 12
  • Thank you for your answers! I didn't know you could use make_optional without specifying the type. Two others related questions came up in my mind. What's the point of using make_optional specifying the template parameter? And why spaghetti has to be of const type? – giubacchio Apr 01 '21 at 16:33
  • 2
    There isn't much point in using `make_optional` if you specify the template parameters. I think you are mistaken about `const`. It either copies or moves it's argument, depending on the value category of the expression – Caleth Apr 01 '21 at 16:40
  • 1
    _"Two others related questions came up in my mind."_ The comments section is not a good place for asking a new question. Consider marking one of these answers correct (it seems that you accept them) and ask a question [in the usual way](https://stackoverflow.com/questions/ask) – Drew Dormann Apr 01 '21 at 16:40
  • 1) I can't think of any reason except if deduction would fail otherwise. If you use C++17 or later you can probably skip `make_optional`. 2) What do you mean by "_has to be `const`_"? – Ted Lyngmo Apr 01 '21 at 16:40
  • Thank you all! Sorry for making an improper use of the comment session; I thought keeping all together would have helped future readers. Anyway I was wrong with the _const_ assumption; I have better explained my doubt in [this](https://stackoverflow.com/questions/66916031/boostmake-optional-with-type-specification) new question – giubacchio Apr 02 '21 at 07:50

2 Answers2

4

make_optional is a convenience or helper function that can reduce the amount of code you have to write by inferring the template parameter of optional. Functionally the two methods are equivalent.

auto pasta = boost::make_optional(spaghetti);
Woodford
  • 3,746
  • 1
  • 15
  • 29
4

Prior to C++17, you couldn't deduce template arguments for a class from it's initialisation, like you could with a function template call.

As a workaround, functions named in the form make_thing that constructed a thing allowed deduction.

auto pasta = boost::make_optional(spaghetti); // pasta is boost::optional<PastaType>

auto pasta = boost::optional(spaghetti); // compile error before C++17, afterward pasta is boost::optional<PastaType>
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • `make_thing` is still useful for `thing>`, as `thing{some_thing}` use copy constructor, whereas `make_thing(some_thing);` really return `thing>`. – Jarod42 Apr 02 '21 at 08:49