На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> iterator
    Привет! :D

    Продолжаю мучить итераторы. Создал еще один итератор для прохода по узлам.
    есть два тупых вопроса :D
    1. зачем СТЛ требует оператор :huh:
    bool operator==(const Node& node, int value);

    2.почему цикл удаления не прекращается (во всяком случае у меня он висит) :huh:
    (он закомментирован) где-то баг я не вижу
    ExpandedWrap disabled
      struct Node {
          int value;
          Node* next;
      };
       
      bool operator==(const Node& node, int value) { //<-- без него не компилирует
          return node.value == value;
      }
       
      class NodeIterator
          : public std::iterator<std::forward_iterator_tag, Node*> {
       
          Node* node;
      public:
          NodeIterator():node(nullptr) { }
          NodeIterator(Node* _node):node(_node) { }
          Node* getNode() const { return node; }
       
          Node& operator*() { return *node; }
          Node* operator->() { return node; }
          NodeIterator& operator++() { node = node->next; return *this; }
      };
       
      bool operator==(const NodeIterator& lhs, const NodeIterator& rhs) {
          return lhs.getNode() == rhs.getNode();
      }
       
      bool operator!=(const NodeIterator& lhs, const NodeIterator& rhs) {
          return !(lhs == rhs);
      }
       
      int main() {
       
          Node* head = new Node();
          head->value = 100;
       
          Node* node1 = new Node();
          node1->value = 101;
          head->next = node1;
       
          Node* node2 = new Node();
          node2->value = 102;
          node1->next = node2;
       
          node2->next = nullptr;
       
          NodeIterator headIterator(head);
          NodeIterator pos = std::find(headIterator, NodeIterator(), 102);
       
          if (pos != NodeIterator())
              std::cout << pos->value << std::endl;
          else
              std::cout << "not found" << std::endl;
       
      //  for (; headIterator != NodeIterator(); ++headIterator) //<-- тут висит
      //      delete headIterator.getNode();
       
          return 0;
      }
    Сообщение отредактировано: Cfon -
      Цитата Cfon @
      1. зачем СТЛ требует оператор
      bool operator==(const Node& node, int value);


      Цитата Cfon @
      NodeIterator pos = std::find(headIterator, NodeIterator(), 102);
        Добавлено
        это я понял, но почему - не понял, вот почему и спросил :D

        Добавлено
        хотя вроде понял да дело в алгоритме std::find

        ExpandedWrap disabled
          template<typename _InputIterator, typename _Tp>
              inline _InputIterator
              find(_InputIterator __first, _InputIterator __last,
               const _Tp& __val)
              {
                // concept requirements
                __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
                __glibcxx_function_requires(_EqualOpConcept<
                  typename iterator_traits<_InputIterator>::value_type, _Tp>) //<-- видимо здесь определяется требование того оператора
                __glibcxx_requires_valid_range(__first, __last);
                return std::__find_if(__first, __last,
                          __gnu_cxx::__ops::__iter_equals_val(__val));
              }


        Добавлено
        остался вопрос что не так с этим циклом

        for (; headIterator != NodeIterator(); ++headIterator)

        я не понимаю почему он не останавливается? :huh:

        Добавлено
        вроде operator!= и operator++ определены правильно :unsure:
        Сообщение отредактировано: JoeUser -
          Цитата Cfon @
          1. зачем СТЛ требует оператор bool operator==

          А затем, что непонятно как объекты сравнивать между собой. Даже в твоем случае два члена класса и непонятно по чему ты хочешь сравнивать по значению или по указателю.

          Добавлено
          Цитата Cfon @
          почему цикл удаления не прекращается

          Вангую, что ты хотел написать:
          for (; headIterator != pos; ++headIterator)

          Добавлено
          А хотя впрочем должно работать и так. Залей на ideone, я не вижу причин висеть этому коду.

          Добавлено
          Ну и использовать конструктор итератора в качестве end неочевидное и неэффективное решение на мой взгляд.
          Сообщение отредактировано: shm -
            Цитата shm @
            Ну и использовать конструктор итератора в качестве end неочевидное и неэффективное решение на мой взгляд.

            shm это классическое решение :D

            Добавлено
            конструктор по умолчанию создает объект в указателем Node* = nullptr

            Добавлено
            Цитата shm @
            Цитата Cfon @
            1. зачем СТЛ требует оператор bool operator==

            А затем, что непонятно как объекты сравнивать между собой. Даже в твоем случае два члена класса и непонятно по чему ты хочешь сравнивать по значению или по указателю.

            спс с этим я разобрался :P
              Цитата Cfon @
              конструктор по умолчанию создает объект в указателем Node* = nullptr

              Я понял. Только это происходит при каждой итерации цикла.
                Цитата shm @
                Цитата Cfon @
                почему цикл удаления не прекращается

                Вангую, что ты хотел написать:
                for (; headIterator != pos; ++headIterator)

                Добавлено
                А хотя впрочем должно работать и так. Залей на ideone, я не вижу причин висеть этому коду.

                не код неверен вот вручную как правильно удалять :D

                ExpandedWrap disabled
                  Node* node = head;
                      while (node != nullptr) {
                          std::cout << "deleted.\n";
                          Node* tmp = node->next;
                          delete node;
                          node = tmp;
                      }
                  Ну так шо с зависоном. У меня ничего не виснет.
                    надо удалять с хвоста а мой итератор может только в головы идти :unsure:

                    Добавлено
                    Цитата shm @
                    Ну так шо с зависоном. У меня ничего не виснет.

                    как не виснет :huh:

                    Добавлено
                    Цитата shm @
                    Цитата Cfon @
                    конструктор по умолчанию создает объект в указателем Node* = nullptr

                    Я понял. Только это происходит при каждой итерации цикла.

                    а ну да :)
                    потом я передам его в for_each там все пучком будет :D
                      Цитата Cfon @
                      не код неверен вот вручную как правильно удалять

                      Я конечно не знаю, после 8ми часов поиска КЗ на новой плате я уже не сильно соображаю, но ошибок не вижу не тут ни там.
                      Сообщение отредактировано: shm -
                        Цитата shm @
                        Цитата Cfon @
                        не код неверен вот вручную как правильно удалять

                        Я конечно не знаю, после 8ми часов поиска КЗ на новой плате я уже не сильно соображаю, но ошибок не вижу не тут ни там.

                        ExpandedWrap disabled
                          for (; headIterator != NodeIterator(); ++headIterator){
                          //      delete headIterator.getNode();
                                  std::cout << "deleted.\n";
                              }


                        сам цикл отрабатывает если не удалять :)

                        Добавлено
                        а если в цикле удалять то висит
                          Цитата Cfon @
                          сам цикл отрабатывает если не удалять

                          А все сообразил. У тебя ++headIterator вызывается после delete headIterator.getNode(), что не есть хорошо.
                            Цитата Cfon @
                            надо удалять с хвоста а мой итератор может только в головы идти :unsure:

                            видимо в этом причина :unsure:

                            Добавлено
                            Цитата shm @
                            А все сообразил. У тебя ++headIterator вызывается после delete headIterator.getNode(), что не есть хорошо.

                            и я о том :)

                            Добавлено
                            что то не соображу можно ли как то код там изменить чтоб было ОК? :unsure:
                              ExpandedWrap disabled
                                for (NodeIterator tmp; headIterator != NodeIterator(); )
                                {
                                   tmp = headIterator;  
                                   ++headIterator;
                                   delete tmp.getNode();
                                }
                              Сообщение отредактировано: shm -
                                Внутри цикла ты делаешь delete узлу списка, а позже в инкременте итератора обращаешься к его полю next.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0536 ]   [ 15 queries used ]   [ Generated: 19.05.24, 14:56 GMT ]