3

これは最小限で、完全で、検証可能な例です。とにかく、構造体を考えると:

struct Foo {
    int even;
    int odd;
};

istream& operator>>(istream& lhs, Foo& rhs) {
    int input;

    lhs >> input;

    (input % 2 == 0 ? rhs.even : rhs.odd) = input;

    return lhs;
}

私は次のことができます:

stringstream bar("1 2 3 4 5 6 7 8 9 0");

for (const auto& i : vector<Foo>{istream_iterator<Foo>(bar), istream_iterator<Foo>()}) {
    cout << i.even << ' ' << i.odd << endl;
}

ただし、これにより結果が得られます。

-1215720516 1
2 1
2 3
4 3
4 5
6 5
6 7
8 7
8 9
0 9

をゼロ初期化するFooには、次のコードを記述できます。

for(Foo i{}; bar >> i; i = Foo{}) {
    cout << i.even << ' ' << i.odd << endl;
}

これにより、m に期待される結果が得られます。

0 1
2 0
0 3
4 0
0 5
6 0
0 7
8 0
0 9
0 0

変数を完全に上書きしない抽出演算子を持つことは大雑把であることを理解しています。これは最初、ここでの私の回答ここでの私の質問に由来しています。私の考えでは、読み取りの合間に変数をゼロ初期化するというより自然な期待がありました。いずれにせよ、変数が読み取り間でゼロ初期化されるように使用することは可能ですか、それとも-loop を使用する必要がありますか?istream_iteratorfor

4

2 に答える 2

1

変数が読み取り間でゼロ初期化されるように istream_iterator を使用することは可能ですか?

istream_iteratorの内部を調べると、次の内部状態があります。

private:
  istream_type* _M_stream;
  _Tp       _M_value;
  bool      _M_ok;

_M_value はデフォルトで構築されます。

it++/++it を使用すると、実装に次の関連行がある _M_read() が呼び出されます。

*_M_stream >> _M_value;

したがって、イテレータ自体はエクストラレータの外で Foo の状態に触れることはなく、_M_value呼び出し間で再利用されます。つまり、何らかの方法で自分で初期化する必要があります。operator>>で妥当なところだと思います。

于 2016-06-07T14:59:09.650 に答える