Search code examples
c++c++17option-typedefault-constructor

How do I obtain a non-empty optional with the value inside it being default constructed?


Let's say I have a default constructed, thus empty, object ov of type std::optional<std::vector<int>>.

Yeah, std::vector can express the concept of being empty without the help of std::optional, but bear with me.

And then let's say that, based on some logic, I decide that I have to fill it with a vector on which I want to push_back elements one by one. How do I do?

It looks to me that the following is a bit ugly:

ov = decltype(ov)::value_type{};
ov.push_back(/* something */);
ov.push_back(/* something else */);

Is this really the way to go about it?


Solution

  • The easiest way is

    std::optional<std::vector<int>> ov = {{}};
    

    alternatives include

    std::optional<std::vector<int>> ov(std::in_place);
    

    sadly there is no way to do this with assignment instead of construction; {{}} is ambiguous, and the std::in_place constructor is explicit.

    There you have to call ov.emplace().

    You could create a helper object;

    struct non_empty {
      template<class T>
      constexpr operator std::optional<T>()const{ return {{}}; }
    };
    

    then

    ov = non_empty{};
    

    does the job.