Enlico
Enlico

Reputation: 28510

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?

Upvotes: 0

Views: 479

Answers (2)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275966

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.

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 474436

For any default-constructible type T, you can create an optional<T> with a default-constructed T via std::optional<T>(std::in_place). This will perform in-place construction with no parameters.

If you already have such an optional<T> instance, you can simply call obj.emplace() on it.

Upvotes: 6

Related Questions