Итератор — это объект с семантикой указателя, который может указывать на N+1 точку в объекте.
Раз он с семантикой указателя, у него есть операции «унарная звезда» и −> (разыменование и разыменование+взятие поля). Также у итератора есть операция ++ (сдвинуться на следующую позицию). Если это т.н. «однонаправленный итератор» — всё, больше ничего.
Также бывают т.н. двунаправленные итераторы (есть операция −−), и итераторы произвольного доступа (их можно свободно складывать с числами — ну совсем как указатели). В частности, у std::list итераторы двунаправленные.
У итераторов неопределённое поведение…
• при попытке выйти за начало или конец;
• при попытке разыменовать, если он смотрит на последнюю позицию (отмеченную как «конец»).
Конкретно о задаче.
1. std::vector предпочтительнее std::list.
2. Не нужно возвращать string*, хватает какого-нибудь контейнера (std::vector<std::string> или std::list<std::string>).
3. Если функциональности и скорости istringstream хватает, флаг в руки! Я бы написал по хардкору, с нуля. Вот мой код, выдранный из моего проекта, наверно, будет несложно переделать его в учебный.
void parseCommaList(
const char *aStart, // указатель на начало
const char *aEnd, // указатель на символ за концом
char aComma, // символ-разделитель
bool aSkipEmpty, // true, если пустые подстроки пропускать
ProcParseCommaList aCallback, // функция-нагрузка
void *aData) // этот параметр нужен, чтобы передавать какие хочешь данные в функцию-нагрузку, удаляй его смело!
{
str::trim(aStart, aEnd); // моя функция; пододвигает aStart вперёд и aEnd назад, убирая пробелы.
// Если удаление пробелов не нужно — удаляй! Если нужно — пиши сам.
if (aStart == aEnd) return;
const char *sstart = aStart;
for (const char *p = aStart; p != aEnd; ++p)
{
if (*p != aComma) continue;
const char *send = p;
str::trim(sstart, send); // то же самое, можно убрать
if (p != sstart || !aSkipEmpty)
aCallback(sstart, send, aData); // замени на боевую нагрузку
sstart = p + 1;
}
str::trim(sstart, aEnd); // то же самое, можно убрать
if (sstart != aEnd || !aSkipEmpty)
aCallback(sstart, aEnd, aData); // замени на боевую нагрузку
}
И, соответственно, версия для std::string.
inline void parseCommaList(
const std::string &aIn,
char aComma,
bool aSkipEmpty,
ProcParseCommaList aCallback,
void *aData)
{
parseCommaList(aIn.data(), aIn.data() + aIn.length(), aComma, aSkipEmpty,
aCallback, aData);
}