Creating own iterator for double vectors

2019-03-06 04:01发布

问题:

I am a bit new at c++, so the question may be without any meaning, so, sorry about that in advance. So, i have a class of hashtable, my hashtable is vector of vectors, it means that i used

std::vector<std::vector<std::string> > htable;

My task is - create own iterator with operation ++, --, -> and *. I wrote this

    class hashTable
{
public: 
    hashTable(int size);
    ~hashTable();
    void add(std::string s);
    bool inHash(std::string s);
    void deletestr(std::string s);
    void printall();
    int maxcoll();

private:
    std::vector<std::vector<std::string> > htable;
    std::vector<std::vector<std::string> > newhtable;
    int hfunc(std::string s);
    void reallocate();
    int M;
    int teksize;
    int issame(std::string a, std::string b);

    class myiterator{
        myiterator();
        myiterator operator*();
        myiterator operator++();
        myiterator operator--();
        myiterator operator->();

    };
    myiterator begin() {return htable.begin()}
    myiterator end() {return htable.end()}

};

I think, that i understand what the interator is, but now i suppose that i was wrong, so when i try to compile this, there is a mistake in lines

myiterator begin() {return htable.begin()}
myiterator end() {return htable.end()}

/Users/ratkke/Programms/c++/mipt/tasks/#5/myhash.cpp:37:29: error: no viable conversion from 'iterator' (aka '__wrap_iter') to 'hashTable::myiterator' myiterator begin() {return htable.begin()} ^~~~~~~~~~~~~~ /Users/ratkke/Programms/c++/mipt/tasks/#5/myhash.cpp:29:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'iterator' (aka '__wrap_iter') to 'const hashTable::myiterator &' for 1st argument class myiterator{

And i don't know why. Also, can you tell me about realisation of iterator(or just link to article) for iterator for vectors, because i can't understand how i must implement all this operators. Thank you in advance.

回答1:

You need to implement your myiterator. There are lots of way to do that, but at very least you must add something to myiterator. For instance

class myiterator{
public:
    myiterator();
    myiterator(std::vector<std::vector<std::string> >& v, int ii, int jj) : 
        vec(v), i(ii), j(jj) {}
    std::string operator*();
    myiterator& operator++(); // prefix operator
    myiterator operator++(int); // postfix operator
    myiterator& operator--(); // prefix operator
    myiterator operator--(int); // postfix operator
    std::string* operator->();
private:
    std::vector<std::vector<std::string> >& vec; // the vector we are iterating over
    int i; // the position in the vector (first dimension)
    int j; // the position in the vector (second dimension)
};

myiterator begin() {return myiterator(htable, 0, 0);}

Lots of other ways to do it, and the above may not be exactly what you want, but hopefully this gives you the idea, myiterator must have some data members that hold the vector being iterated over and the position reached so far.

Also note the return type of operator* is wrong, it should (presumably) be std::string. Some of the other operators don't look right either, I've put what I think is correct in the code.