How to assign “nothing” to std::optional<T>?

て烟熏妆下的殇ゞ 提交于 2020-03-21 11:32:16

问题


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:

  1. my_opt.reset(). Just directly set the optional to a disengaged state.

  2. my_opt = std::nullopt; This uses operator=() overload #1

  3. my_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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!