如何从std :: optional <T>移动

han*_*aad 21 c++ std boost-optional c++14

考虑以下示例,我们解析数据并将结果传递给下一个函数:

Content Parse(const std::string& data);
void Process(Content content);

int main()
{
    auto data = ReadData();
    Process(Parse(data));    
}
Run Code Online (Sandbox Code Playgroud)

现在让我们使用更改代码std::optional来处理失败的解析步骤:

optional<Content> Parse(const std::string& data);
void Process(Content content);

int main()
{
    auto data = ReadData();
    auto content = Parse(data);
    if (content)
        Process(move(*content));
}
Run Code Online (Sandbox Code Playgroud)

移动是否有效optional<T>::value()?如果它std::optional可以,它也有效boost::optional吗?

mav*_*vam 16

它是有效的,optional<T>::value()因为它返回一个可变引用,并且该移动不会破坏该对象.如果optional实例不参与,value()将抛出一个bad_optional_access异常(§20.6.4.5).

您明确检查是否使用该选项:

if (content)
    Process(move(*content));
Run Code Online (Sandbox Code Playgroud)

但是您不使用该成员value()来访问底层证券T.请注意,value()在返回有效值之前在内部执行检查T&,与operator*此不同,前提条件optional实例应该被使用.这是一个微妙的区别,但你使用正确的习语:

if (o)
  f(*o)
Run Code Online (Sandbox Code Playgroud)

而不是

if (o)  // redundant check
  f(o.value())
Run Code Online (Sandbox Code Playgroud)

在Boost中,情况略有不同:首先,没有调用value()提供已检查访问权限的成员函数.(bad_optional_access例外情况根本不存在).该成员get()只是一个别名,operator*并且始终依赖于用户检查optional实例是否已参与.

  • 唔。`value_or` 有一个 `&amp;&amp;` 和 `&amp;` 重载。`value` 不会(为什么不?天真地说,它应该)。我可以看到不想要一个“&amp;&amp;”“运算符*”,以防人们在不检查“可选”是否首先使用的情况下尝试“*”,但是通过抛出“值”,我看不出有什么危害? (2认同)