Я пытаюсь начать работу с 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);
}
Вы не хотите реализовывать функцию
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
копии с одного итератор другому. Но вы не копируете с итератора. Вы вставляете элементы по одному, и вы делаете это, разыменовывая итератор, как если бы он был указателем, а затем увеличивая его, когда вы закончите.
Std :: back_insert_iterator действительно громоздко использовать напрямую. Вместо этого используйте шаблонную функцию std :: back_inserter (она делает для вас все аргументы шаблона).
Тогда ваши readResults станут примерно такими:
std::copy(std::istream_iterator<Result>(is), std::istream_iterator<Result>(), std::back_inserter(v));
При условии, что у вас перегружен оператор >> для результата.
Вы хотите создать функцию чтения для вашего 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()
функция с подходящим итератором.