问题
Reading about std::optional, I'm confused about what is the standard way to assign a value of something and nothing to an optional
.
I guess operator=
would be the standard mechanism to assign a value to an optional. Seems to work. Does this imply a copy of the underlying object?
What is the standard method to assign nothing? I've seen x = {}
(which makes no sense to me as {}
is an empty block) and x = std::nullopt
.
回答1:
I wouldn't say there is one "standard" way to assign nothing to std::optional.
If you read the proposal for std::optional
("A proposal to add a utility class to represent optional objects") the authors present two ways, in this order:
We put the extra requirements in the standardese to make sure that the following syntax works for resetting the optional:
op = {};
We consider that this will become a common idiom for resetting (putting into default-constructed state) values in C++
Note that it is not the only way to disengage an optional object. You can also use:
op = std::nullopt;
std::optional::reset
did not exist at the time of writing that proposal, so it was not mentioned, however it is also a valid way to do it.
回答2:
This is a choose your own adventure. You have three options:
my_opt.reset(). Just directly set the optional to a disengaged state.
my_opt = std::nullopt;
This uses operator=() overload #1my_opt = {};
This uses operator=() overload #3.
Yes, (3) uses the optional
's move assignment operator (a default-constructed optional
is disengaged, so this does the right thing). This is because {}
will not match the std::nullopt_t constructor, and the perfect-forward assignment (overload #4) would be less preferred in the case where T
is constructible from {}
because it's a template.
(1) and (2) always work, regardless of T
. (3) only works if T
is move assignable, because we're going through the assignment operator. But (3) is the shortest. So YMMV.
If (3) makes no sense to you, that's fine, don't use it. Braced-init-lists are a particularly odd part of the language, and you can't go wrong with reset()
or assigning to nullopt
.
来源:https://stackoverflow.com/questions/47441623/how-to-assign-nothing-to-stdoptionalt