Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.143.223.33] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Привет!
Продолжаю мучить итераторы. Создал еще один итератор для прохода по узлам. есть два тупых вопроса 1. зачем СТЛ требует оператор bool operator==(const Node& node, int value); 2.почему цикл удаления не прекращается (во всяком случае у меня он висит) (он закомментирован) где-то баг я не вижу 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; } |
Сообщ.
#2
,
|
|
|
Цитата Cfon @ 1. зачем СТЛ требует оператор bool operator==(const Node& node, int value); Цитата Cfon @ NodeIterator pos = std::find(headIterator, NodeIterator(), 102); |
Сообщ.
#3
,
|
|
|
Добавлено
это я понял, но почему - не понял, вот почему и спросил Добавлено хотя вроде понял да дело в алгоритме std::find 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) я не понимаю почему он не останавливается? Добавлено вроде operator!= и operator++ определены правильно |
Сообщ.
#4
,
|
|
|
Цитата Cfon @ 1. зачем СТЛ требует оператор bool operator== А затем, что непонятно как объекты сравнивать между собой. Даже в твоем случае два члена класса и непонятно по чему ты хочешь сравнивать по значению или по указателю. Добавлено Цитата Cfon @ почему цикл удаления не прекращается Вангую, что ты хотел написать: for (; headIterator != pos; ++headIterator) Добавлено А хотя впрочем должно работать и так. Залей на ideone, я не вижу причин висеть этому коду. Добавлено Ну и использовать конструктор итератора в качестве end неочевидное и неэффективное решение на мой взгляд. |
Сообщ.
#5
,
|
|
|
Цитата shm @ Ну и использовать конструктор итератора в качестве end неочевидное и неэффективное решение на мой взгляд. shm это классическое решение Добавлено конструктор по умолчанию создает объект в указателем Node* = nullptr Добавлено Цитата shm @ Цитата Cfon @ 1. зачем СТЛ требует оператор bool operator== А затем, что непонятно как объекты сравнивать между собой. Даже в твоем случае два члена класса и непонятно по чему ты хочешь сравнивать по значению или по указателю. спс с этим я разобрался |
Сообщ.
#6
,
|
|
|
Цитата Cfon @ конструктор по умолчанию создает объект в указателем Node* = nullptr Я понял. Только это происходит при каждой итерации цикла. |
Сообщ.
#7
,
|
|
|
Цитата shm @ Цитата Cfon @ почему цикл удаления не прекращается Вангую, что ты хотел написать: for (; headIterator != pos; ++headIterator) Добавлено А хотя впрочем должно работать и так. Залей на ideone, я не вижу причин висеть этому коду. не код неверен вот вручную как правильно удалять Node* node = head; while (node != nullptr) { std::cout << "deleted.\n"; Node* tmp = node->next; delete node; node = tmp; } |
Сообщ.
#9
,
|
|
|
надо удалять с хвоста а мой итератор может только в головы идти
Добавлено как не виснет Добавлено Цитата shm @ Цитата Cfon @ конструктор по умолчанию создает объект в указателем Node* = nullptr Я понял. Только это происходит при каждой итерации цикла. а ну да потом я передам его в for_each там все пучком будет |
Сообщ.
#10
,
|
|
|
Цитата Cfon @ не код неверен вот вручную как правильно удалять Я конечно не знаю, после 8ми часов поиска КЗ на новой плате я уже не сильно соображаю, но ошибок не вижу не тут ни там. |
Сообщ.
#11
,
|
|
|
Цитата shm @ Цитата Cfon @ не код неверен вот вручную как правильно удалять Я конечно не знаю, после 8ми часов поиска КЗ на новой плате я уже не сильно соображаю, но ошибок не вижу не тут ни там. for (; headIterator != NodeIterator(); ++headIterator){ // delete headIterator.getNode(); std::cout << "deleted.\n"; } сам цикл отрабатывает если не удалять Добавлено а если в цикле удалять то висит |
Сообщ.
#12
,
|
|
|
Цитата Cfon @ сам цикл отрабатывает если не удалять А все сообразил. У тебя ++headIterator вызывается после delete headIterator.getNode(), что не есть хорошо. |
Сообщ.
#13
,
|
|
|
Цитата Cfon @ надо удалять с хвоста а мой итератор может только в головы идти видимо в этом причина Добавлено Цитата shm @ А все сообразил. У тебя ++headIterator вызывается после delete headIterator.getNode(), что не есть хорошо. и я о том Добавлено что то не соображу можно ли как то код там изменить чтоб было ОК? |
Сообщ.
#14
,
|
|
|
for (NodeIterator tmp; headIterator != NodeIterator(); ) { tmp = headIterator; ++headIterator; delete tmp.getNode(); } |
Сообщ.
#15
,
|
|
|
Внутри цикла ты делаешь delete узлу списка, а позже в инкременте итератора обращаешься к его полю next.
|