10

古いコードを見ると、次のようなものがたくさんあります。

// This is dumb
string do_something(int in)
{
    stringstream out;
    try
    {
        out << std::fixed << in;
    }
    catch(std::exception &e)
    {
        out << e.what();
    }

    return out.str();
}

// Can't we just do this? Can this ever fail?
string do_something_better(int in)
{
    stringstream out;
    out << std::fixed << in;
    return out.str();
}

文字列ストリームがプリミティブを読み取るときに、例外をスローすることはできますか?文字列を読むときはどうですか?

4

2 に答える 2

11

いくつかの答えを要約すると

デフォルトでは、ストリームは例外をスローしません。有効になっている場合は可能です。

stringstream out;
out.exceptions(std::ios::failbit);   // throw exception if failbit gets set

Apache C++ 標準ライブラリ ユーザーズ ガイドによると

フラグ std::ios_base::badbit は、基になるストリーム バッファーに問題があることを示します。これらの問題は次の可能性があります。

メモリ不足。バッファの作成に使用できるメモリがないか、バッファのサイズが他の理由 (ストリームの外部から提供されたなど) で 0 であるか、std::ios_base:: のように、ストリームが独自の内部データにメモリを割り当てることができません。 iword() および std::ios_base::pword()。

基になるストリーム バッファーが例外をスローします。ストリーム バッファは、メモリ不足、コード変換の失敗、または外部デバイスからの回復不能な読み取りエラーなどにより、完全性を失う可能性があります。ストリーム バッファは、例外をスローすることによってこの整合性の喪失を示すことができます。例外はストリームによってキャッチされ、ストリームの状態に badbit が設定されます。

通常、badbit は回復不可能なエラー状況を示し、failbit は失敗した操作を再試行できる可能性がある状況を示すことに注意してください。

したがって、これを行う最も安全な方法は

string do_something(int in)
{
    stringstream out; // This could throw a bad_alloc
    out << std::fixed << in; // This could set bad or fail bits

    if(out.good())
    {
        return out.str();
    }
    else
    {
        return "";
    }
}

ただし、ストリームの作成が失敗した場合のbad_alloc の処理によると、心配すべきより大きな問題があり、プログラムはおそらく終了するため、これはやり過ぎです。したがって、ストリームの作成を過ぎたと仮定すると、badbit が設定される可能性は非常に低いです。(ストリームはメモリ < sizeof(int) で割り当てられます)。

また、failbit が設定される可能性はほとんどありません (破損したスタック以外のスタックから読み取るユースケースについては不明です)。したがって、この時点でストリーム エラーから回復する可能性は低いため、次のコードで十分です。

string do_something(int in)
{
    stringstream out;
    out << std::fixed << in;
    return out.str();
}
于 2012-07-09T17:36:27.610 に答える
2

を含むすべてのストリームは、読み取り時にistringstreams例外をスローできます (で制御可能)。ios::exceptions入力がなくなったとき。さらに、メモリが不足している場合 (たとえば、現在読み取られている文字列を構築する場合) にスローされる可能性があります。

ただし、コード例は書き込み(?) AFAIK書き込みを実行intし、明らかなメモリ不足エラー(コードがうまく処理できない)を除いて、例外を生成するべきではありません。

于 2012-07-07T21:19:01.623 に答える