29

データを解析し、結果を次の関数に渡す次の例を考えてみましょう。

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

4

2 に答える 2

26

optional<T>::value()変更可能な参照を返し、移動によってオブジェクトが破棄されないため、移動元として有効です。optionalインスタンスが関与していない場合、例外value()がスローされbad_optional_accessます (§20.6.4.5)。

オプションが使用されているかどうかを明示的に確認します。

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

value()ただし、メンバーを使用して基になる にアクセスすることはありませんTvalue()は、有効な を返す前に内部的にチェックを実行することに注意してください。これは、インスタンスが関与しているという前提条件T&があるのとは異なります。これは微妙な違いですが、正しいイディオムを使用しています。operator*optional

if (o)
  f(*o)

とは対照的に

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

Boost では状況が少し異なります。まず、value()チェックされたアクセスを提供するメンバー関数が呼び出されません。(bad_optional_access例外は単に存在しません)。メンバーget()は単なるエイリアスであり、インスタンスが関与しoperator*ていることを確認するユーザーに常に依存しています。optional

于 2013-07-06T12:39:25.003 に答える