Search code examples
c++iteratoristream

Using back_insert_iterator in C++


I'm trying to get started with C++, and should implement the function:

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

The function reads lines of the form "studentId grade" from istream and should add them to a vector type using insertIt.

Result is a struct with:

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

Can you give me a hint on how to get started?

I have tried something like this:

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

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

Solution

  • You don't want to implement the function

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

    What you want to do is instead implement the template function

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

    When you pass std::back_inserter(vec), the template will automatically be instantiated to the right type.

    The code for this function will essentially be

    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 copies from one iterator to another. But you're not copying from an iterator. You're inserting elements one at a time, and you do this by dereferencing the iterator, as though it's a pointer, and then incrementing it when you're done.