3

私はC++を使い始めようとしていますが、次の関数を実装する必要があります。

std::istream& readResults(std::istream& is, std::back_insert_iterator<std::vector<Result>> insertIt)

この関数は、istreamから「studentIdgrade」形式の行を読み取り、insertItを使用してそれらをベクトル型に追加する必要があります。

結果は次の構造体です。

struct Result
{
  std::string studentId;
  size_t grade;
};

始める方法についてのヒントを教えてください。

私はこのようなことを試しました:

std::string studentId;
size_t grade;
Result new_result;

while(is >> studentId >> grade) {
    Result new_result = {studentId, grade};
    copy(new_result, *insertIt);
    }
4

3 に答える 3

4

関数を実装したくない

std::istream& readResults(
    std::istream& is,
    std::back_insert_iterator<std::vector<Result>> insertIt)

あなたがしたいことは、代わりにテンプレート関数を実装することです

template<class InsertIterator>
std::istream& readResults(std::istream& is, InsertIterator insertIt)

を渡すstd::back_inserter(vec)と、テンプレートは自動的に適切な型にインスタンス化されます。

この関数のコードは基本的に次のようになります。

template<class InsertIterator>
std::istream& readResults(std::istream& is, InsertIterator insertIt) {
  std::string studentId;
  size_t grade;
  while (is >> studentId >> grade) {
    Result new_result = {studentId, grade};
    *(insertIt++) = new_result;
  }
}

std::copyあるイテレータから別のイテレータにコピーします。しかし、イテレータからコピーしていません。一度に 1 つずつ要素を挿入します。イテレータをポインターのように逆参照し、完了したらインクリメントします。

于 2012-09-23T22:17:12.027 に答える
3

std::back_insert_iterator を直接使用するのは本当に面倒です。代わりにテンプレート関数 std::back_inserter を使用してください (すべてのテンプレート引数の推論を行います)。

readResults は次のようになります。

std::copy(std::istream_iterator<Result>(is), std::istream_iterator<Result>(), std::back_inserter(v));

Result に operator>> をオーバーロードした場合。

于 2012-09-23T21:31:58.097 に答える
1

Resultの読み取り関数、つまり次のように宣言されたものを作成したいとします。

std::istream& operator>> (std::istream& in, Result& result)
{
    // read your result here
    return in;
}

これが整っていれば、 の実装はreadResult()かなり簡単になります。

std::copy(std::istream_iterator<Result>(is), std::istream_iterator<Result>(), insertIt);

それ以外はreadResult()、適切なイテレータを使用して関数を呼び出すだけです。

于 2012-09-23T21:29:06.753 に答える