如何在C++中实现可迭代的LinkedList类?
解决C++ LinkedList迭代问题:替代Python yield的实现方案
C没有Python的yield关键字,要让LinkedList支持迭代,需要遵循C的迭代器规范,以下是两种可行方案:
方案1:自定义迭代器(兼容C++11及以上)
这是最通用的实现方式,通过手写迭代器类让LinkedList符合C++容器的迭代要求。
完整代码示例
#include <iostream> #include <iterator> // 用于迭代器类别标签 template <typename T> struct Node { T data; Node* next; Node(const T& val) : data(val), next(nullptr) {} }; template <typename T> class LinkedList { private: Node<T>* head; public: LinkedList() : head(nullptr) {} // 向链表尾部添加元素 void push_back(const T& val) { if (!head) { head = new Node<T>(val); return; } Node<T>* curr = head; while (curr->next) { curr = curr->next; } curr->next = new Node<T>(val); } // 嵌套迭代器类,满足C++前向迭代器要求 class Iterator { private: Node<T>* current; public: // 迭代器类型定义,必须指定以兼容标准库 using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; explicit Iterator(Node<T>* node) : current(node) {} // 解引用运算符 reference operator*() const { return current->data; } // 箭头运算符 pointer operator->() const { return ¤t->data; } // 前置递增 Iterator& operator++() { if (current) current = current->next; return *this; } // 后置递增 Iterator operator++(int) { Iterator temp = *this; ++(*this); return temp; } // 相等/不等判断 bool operator==(const Iterator& other) const { return current == other.current; } bool operator!=(const Iterator& other) const { return !(*this == other); } }; // 返回起始迭代器,对应Python的__iter__逻辑 Iterator begin() const { return Iterator(head); } // 返回尾后迭代器 Iterator end() const { return Iterator(nullptr); } // 可选:添加与Python同名的__iter__函数,内部返回begin() Iterator __iter__() const { return begin(); } // 析构函数,释放内存避免泄漏 ~LinkedList() { Node<T>* curr = head; while (curr) { Node<T>* next = curr->next; delete curr; curr = next; } } }; // 使用示例 int main() { LinkedList<int> list; list.push_back(1); list.push_back(2); list.push_back(3); // 范围for循环(C++11及以上支持) for (int num : list) { std::cout << num << " "; } std::cout << "\n"; // 手动迭代器遍历 auto it = list.__iter__(); while (it != list.end()) { std::cout << *it << " "; ++it; } std::cout << "\n"; return 0; }
说明
- 自定义迭代器需要实现解引用、递增、相等判断等核心运算符,并指定迭代器类别(这里用
std::forward_iterator_tag,适配单向链表的遍历特性)。 begin()返回指向链表头节点的迭代器,end()返回指向空的尾后迭代器,这是C++容器的标准接口。- 添加的
__iter__函数只是内部调用begin(),和Python的迭代入口逻辑对齐。
方案2:C20协程模拟yield(需C20支持)
如果你的编译器支持C++20,可以用协程的co_yield关键字模拟Python的yield行为,写法更接近Python的习惯。
完整代码示例
#include <iostream> #include <coroutine> #include <iterator> template <typename T> struct Node { T data; Node* next; Node(const T& val) : data(val), next(nullptr) {} }; // 封装协程的Generator类,提供可迭代接口 template <typename T> class Generator { public: struct promise_type { T current_value; // 协程暂停并返回当前值 std::suspend_always yield_value(T value) { current_value = value; return {}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } Generator get_return_object() { return Generator{std::coroutine_handle<promise_type>::from_promise(*this)}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; using handle_type = std::coroutine_handle<promise_type>; explicit Generator(handle_type h) : coro(h) {} ~Generator() { if (coro) coro.destroy(); } // 禁用拷贝,允许移动 Generator(const Generator&) = delete; Generator& operator=(const Generator&) = delete; Generator(Generator&& other) noexcept : coro(other.coro) { other.coro = nullptr; } Generator& operator=(Generator&& other) noexcept { if (this != &other) { if (coro) coro.destroy(); coro = other.coro; other.coro = nullptr; } return *this; } // 迭代器实现 struct iterator { handle_type coro; bool done = false; using iterator_category = std::input_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = const T*; using reference = const T&; iterator() = default; explicit iterator(handle_type h) : coro(h) { done = coro && coro.done(); } reference operator*() const { return coro.promise().current_value; } pointer operator->() const { return &coro.promise().current_value; } iterator& operator++() { coro.resume(); done = coro.done(); return *this; } bool operator==(const iterator& other) const { return done == other.done; } bool operator!=(const iterator& other) const { return !(*this == other); } }; iterator begin() { return iterator{coro}; } iterator end() { return iterator{}; } private: handle_type coro; }; template <typename T> class LinkedList { private: Node<T>* head; public: LinkedList() : head(nullptr) {} void push_back(const T& val) { if (!head) { head = new Node<T>(val); return; } Node<T>* curr = head; while (curr->next) { curr = curr->next; } curr->next = new Node<T>(val); } // 协程版__iter__,用co_yield返回元素 Generator<T> __iter__() const { Node<T>* curr = head; while (curr) { co_yield curr->data; // 模拟Python的yield curr = curr->next; } } ~LinkedList() { Node<T>* curr = head; while (curr) { Node<T>* next = curr->next; delete curr; curr = next; } } }; // 使用示例 int main() { LinkedList<int> list; list.push_back(1); list.push_back(2); list.push_back(3); // 遍历__iter__返回的Generator for (int num : list.__iter__()) { std::cout << num << " "; } std::cout << "\n"; return 0; }
说明
Generator类封装了协程的底层逻辑,让协程返回的对象支持迭代。__iter__作为协程函数,用co_yield逐个返回链表元素,写法和Python的__iter__几乎一致。- 注意:需要编译器开启C++20支持(比如GCC加
-std=c++20,MSVC加/std:c++20)。
内容的提问来源于stack exchange,提问作者asker
相关产品推荐
相关产品推荐

