iterator — Использование back_insert_iterator в переполнении стека

Я пытаюсь начать работу с C ++ и должен реализовать функцию:

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

Функция читает строки вида «studentId grade» из istream и должна добавить их к векторному типу, используя 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);
}

1

Решение

Вы не хотите реализовывать функцию

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

Другие решения

Std :: back_insert_iterator действительно громоздко использовать напрямую. Вместо этого используйте шаблонную функцию std :: back_inserter (она делает для вас все аргументы шаблона).

Тогда ваши readResults станут примерно такими:

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

При условии, что у вас перегружен оператор >> для результата.

3

Вы хотите создать функцию чтения для вашего 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() функция с подходящим итератором.

1
По вопросам рекламы [email protected]