【发布时间】:2022-01-14 17:48:35
【问题描述】:
我正在使用旧版 C 代码,而新代码是用 C++ 编写的。为了使用 C++ 标准库,我在阅读了 Bjarne Stroustrup 在Adaptation 上的博客文章后,为旧版LinkedList 编写了一个简单的Iterator,如下所示。
我的问题是:
-
我想为另一个
struct创建另一个Iterator,比如struct TokenList。我不确定如何使用namespace并且仍然能够使用 range-basedfor循环。任何指针都会有所帮助。 -
Iterator即:begin、end、++、*、!=的适配器是否正确?目前,我有兴趣使用基于范围的for循环阅读LinkedList的内容。
#include <cstdio>
#include <numeric>
#include <algorithm>
struct LinkedList {
double v;
LinkedList *next;
};
struct Iterator {
LinkedList *current;
LinkedList &c;
};
Iterator begin(LinkedList *c) { return Iterator {c, *c}; }
Iterator end(LinkedList *c) { return Iterator {nullptr, *c}; }
Iterator &operator++(Iterator &p) { p.current = p.current->next; return p; }
LinkedList *operator*(Iterator p) { return p.current; }
bool operator!=(Iterator lhs, Iterator rhs) { return (lhs.current != rhs.current); }
int main()
{
LinkedList *node1 = new LinkedList;
LinkedList *node2 = new LinkedList;
LinkedList *node3 = new LinkedList;
node1->v = 1; node1->next = node2;
node2->v = 2; node2->next = node3;
node3->v = 3; node3->next = nullptr;
printf("// C style: iteration\n");
for (auto ptr = node1; ptr; ptr = ptr->next) {
printf("%e\n", ptr->v);
}
auto head = node1;
// make use of begin(), end(), ++, != and *
printf("// Modern C++ style: range based for-loop\n");
for (const auto& it : head) {
printf("%e\n", it->v);
}
delete node3;
delete node2;
delete node1;
return 0;
}
【问题讨论】:
-
实现一个人拥有的链表是一个有用的编程练习,几乎在每一个编程入门课程中都有。但是当一个人面临真正的任务时,简单地使用
std::list会简单得多。您能否阐明您正在尝试解决的具体问题,使用您自己的链表实现,不能简单地通过使用std::list来解决,以及随之而来的一切? -
旧代码似乎还是需要一些返工。
LinkedList是链表中的一个节点。完全混乱。 -
命名空间与此有什么关系?您的迭代器类应该属于您的容器,而不是全局范围级别。在迭代器中存储参考值是没有意义的。超级粗略。不要那样做。
-
请注意您的删除不正确。您不能在已删除的节点上推进迭代器。
-
获得基于范围的 for 循环的最佳方法是将 C 样式的链表包装在一个类中,该类执行与库容器相同的基本任务,并具有与图书馆容器。 Helpful link