Это будет легче увидеть, потянув hophop
из класса datas
. Теперь вы можете увидеть конструктор hophop
и его задачи. Я бы удалил возвращаемое значение ++operator
, установил бы его void, чтобы указать, что здесь он ничего не делает.
#include <iostream>
class hophop {
private:
const char* pos, next;
public:
hophop(const char* p, char m) : pos(p), next(m) {}
char operator *() { return *pos; }
hophop operator ++() {
++pos;
while (*(pos + 1) != next)
++pos;
return *this;
}
bool operator !=(const hophop& o) { return pos < o.pos; }
};
class datas {
private:
using iterator = hophop;
const char* string, marker;
const int len;
public:
datas(const char* d, int l, char m) : string(d), len(l), marker(m) {}
iterator begin() { return hophop(string, marker); }
iterator end() { return hophop(string + len, marker); }
};
int main(void) {
datas chars("we are where we were", 20, 'e');
// w r h r w w r
for (char c : chars)
std::cout << c;
std::cout << "\nusing a non range based for loop:" << std::endl;
for (hophop it = chars.begin(); it != chars.end(); ++it)
std::cout << *it;
std::cout << "\nor where the return value could be used:" << std::endl;
auto it = chars.begin();
std::cout << *it;
for (; it != chars.end();)
std::cout << *++it;
}
Так что теперь может быть проще увидеть, как работает оператор hophop ++ за работой. operator *()
вызывается в начале l oop, поэтому независимо от того, какой первый символ, его извлекают. Затем вызывается ++operator
, и он перемещает итератор как минимум один раз вперед и до тех пор, пока он не совпадет с next
. Затем он возвращает символ перед матчем. Посмотрите на комментарий в основном. Возвращается первый и каждый символ перед e
.
Если вы не часто используете отладчик, вам следует это сделать. поместив точку останова в operator++
, вы сможете увидеть, что происходит.
ОБНОВЛЕНИЕ
Ранее я установил значение возврата ++operator
в void. Как указывает @JaMiT, для оператора целесообразно возвращать *this
. Я также добавил еще два цикла, они должны быть понятнее, чем использование диапазона на основе l oop. Третий пример на самом деле использует возвращаемое значение ++operator
, первые два цикла - нет.
И привычка не using namespace std;
Это спасет вас от неприятностей в будущем.