1

In the following code the output is "wrhrwwr", I try to understand what the iterator is doing, also how the "++" is overloaded. It seems like it somehow skips the 'e'. However, the code is very unclear to me, maybe I can be helped. Thank you

#include <iostream> 

using namespace std;

class datas {
private: 
    const char *string,marker;
    const int len;
public:
    class hophop {
    private:
        const char *pos, next;
    public: 
        char operator *() { return *pos; }
        hophop operator ++() {++pos;while (*(pos+1)!=next)  ++pos; return *this; }
        bool operator !=(hophop &o) { return pos < o.pos; }
        hophop(const char *p, char m) : pos(p),next(m) {}
    };
    typedef hophop iterator;
    iterator begin() { return hophop (string, marker); }
    itrator end () { return hophop(string +len ,marker); }
    datas(const char *d,int l, char m) : string (d), len(l),marker(m){}
};

int main( void ) {

    datas chars ("we are where we were", 20, 'e');
    for (char c: chars)
        cout << c;

    return 0;
}
Pete Fordham
  • 2,278
  • 16
  • 25
domicpp.
  • 19
  • 2

1 Answers1

1

It will be easier to see by pulling hophop out of the datas class. Now you can see the hophop constructor and what it is up to. I would have removed the return value of the ++operator, set it to void, to point out it does nothing here.

#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;
}

So now it may be easier to see how the hophop ++ operator is working. operator *() gets called at the beginning of the loop so no matter what the first character is, it gets retrieved. Then the ++operator is called and it moves the iterator at least once forward and until it matches next. Then it returns the character before the match. Look at the comment in main. The first and every character before the e is returned.

If you have not used a debugger much, you should. by putting a break point in operator++ you can see what is happening.

UPDATE

I had previously set the return value of the ++operator to void. As @JaMiT points out, it is appropriate for the operator to return *this. I've also added two more loops, they should be clearer than using a range based loop. The third example actually uses the return value of the ++operator, the first two loops don't.

And, get in the habit of not using namespace std; It will save you from troubles down the road.

lakeweb
  • 1,859
  • 2
  • 16
  • 21
  • Thanks!,that one really helped me a lot. So the ++operator didnt return anything usefull in my code? – domicpp. Jan 25 '20 at 01:15
  • You are welcome. Yes, the `for` loop in main just calls the `++operator` to move the iterator. It does not look for, or do anything, with a return value. – lakeweb Jan 25 '20 at 01:43
  • [It is idiomatic for `operator++()` to return `*this`](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading/4421719#4421719). Changing code to deviate from this convention is probably not a good idea when dealing with someone still learning the conventions. Especially when there is so little gained (a single line simpler) by doing so. *(I will grant that breaking that function over multiple lines is a good approach.)* – JaMiT Jan 25 '20 at 04:21