2013-11-10 2 views
0

я есть 2d вектор для моего HashtableРеализация префикса оператора

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

и класса для итератора.

class myiterator{ 
    public: 
     myiterator(); 
     myiterator(std::vector<std::vector<std::string> >& v, int ii, int jj) : 
      vec(v), i(ii), j(jj) {} 
     myiterator& operator++(); // prefix operator 
     myiterator& operator--(); // prefix 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() { 
     int start=0; 
     while(htable[start].size()==0){ 
      start++; 
     } 
     return (myiterator(htable, start, 0)); 
    } 
    myiterator end(){ 
     int end=htable.size()-1; 
     while(htable[end].size()==0){ 
      end--; 
     } 
     return (myiterator(htable, end, htable[end].size()-1)); 
    } 

Я реализовал начало и конец итератора, но я понятия не имею, как и что делать с оператором приставкой. Кроме того, я не мог google, какой оператор «->» есть? Итак, пожалуйста, можете ли вы дать мне небольшой трюк или статью об истребителях префиксов реализации для векторов 2d? Заранее спасибо.

+0

Вот как вы overloasd пре-/постфикса операторы в C++: http://stackoverflow.com/questions/894804/how-to-differentiate-when-overloading-between-prefix- and-postfix-forms-of-oper – LumpN

ответ

3

operator-> является оператором разыменования. Он позволяет вам писать it->myFunc() (то есть, чтобы итератор вел себя как указатель). Как правило, вы возвращаете тип, на который указывает ваш итератор.

Ваши префиксные операторы (operator++ и operator--) должны переместить итератор на следующий и предыдущие элементы соответственно.

Как примечание стороны, если вы перегружать operator->, вы также должны перегружать operator*(), и вы, вероятно, захотите также перегружать операторы после починки myiterator operator--(int) и myiterator operator++(int).

+1

+1 Примечание: реализация последних (постфиксных) операторов делает * not * возвращает ссылку на итератор, на котором они запускаются. В обоих случаях новый итератор результата с бай-илом строится с текущим состоянием '* this' ** до ** модификации. Затем обновляется '* this' (расширенный или отложенный), а значение by-val temp - это возвращаемое значение, как' iterator', * not * как 'iterator &'. Это основная причина, по которой операторы постфикса более дорогие, чем префикс, который просто продвигает/отступает итератор и возвращает '* this' как' iterator & '. – WhozCraig

+0

Хорошая точка. Добавлено значение возврата, чтобы продемонстрировать эту точку. :) –

+0

Извините за мой вопрос nooby, но что это такое? – ratkke

1

Когда вы увеличиваете свой итератор, вы в основном делаете то же самое, что и для начала().

if (j == htable[i].size() - 1) // j is at the end of the inner vector 
    // set j to zero 
    // increment i until htable[i] is not the end of the outer vector and is not empty 
else 
    // increment j 

В качестве стороны я бы рекомендовал использовать итераторы вектора вместо i и j. Например:

class MyIterator 
{ 
    std::vector< std::vector<std::string> >::iterator i; 
    std::vector<std::string>::iterator j; 

    // ... 
} 

MyIterator begin() 
{ 
    std::vector< std::vector<std::string> >::iterator o_iter = htable.begin(); 
    while (o_iter != htable.end() && o_iter->empty()) 
    ++o_iter; 

    // assuming htable wasn't empty... 
    return MyIterator(htable, o_iter, o_iter->begin()); 
} 
+0

Что вы подразумеваете под «использованием итераторов вектора». – ratkke

+0

checkout the edit – Carl

+0

Спасибо, но можете ли вы объяснить, пожалуйста, эти две строки: std :: vector > :: iterator o_iter = htable.begin(); ' и 'return MyIterator (htable, o_iter, o_iter-> begin()); Я не понял твоей идеи. Заранее спасибо – ratkke

Смежные вопросы