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