如何从标准::可选<T>移动

How to move from std::optional<T>

本文关键字:移动 gt lt 可选 标准      更新时间:2023-10-16

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

Content Parse(const std::string& data);
void Process(Content content);
int main()
{
    auto data = ReadData();
    Process(Parse(data));    
}

现在,让我们使用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));
}

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

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

您明确检查选项是否已启用:

if (content)
    Process(move(*content));

但是您不使用成员value()来访问底层T。请注意,value()在返回有效的T&之前会在内部执行检查,而operator*有一个先决条件,即optional实例应参与。这是一个微妙的区别,但你使用了正确的习语:

if (o)
  f(*o)

与相反

if (o)  // redundant check
  f(o.value())

在Boost中,情况略有不同:首先,不存在名为value()的成员函数,该函数提供检查访问。(bad_optional_access异常根本不存在)。成员get()只是operator*的别名,并且总是依赖于用户检查optional实例是否参与。

对于您当前的实现,答案是否定的。但如果您稍微更改它,您就可以移动值。optional的运算符*(以及方法value())有4个重载。其中只有2个返回右值引用(_Ty&const_Ty&aamp;amp&常量&amp。这意味着只有当您的可选变量本身被右值引用访问时,您才能使用它们。在这种情况下,实现应该看起来像:

std::optional<Content> Parse(const std::string& data);
void Process(Content content);
int main()
{
    auto data = ReadData();
    auto content = Parse(data);
    if (content)
        Process(*std::move(content));
}