遍历list统计元素出现次数时编译报错,求排查代码问题
问题分析与解决办法
你的编译错误是个很典型的C++迭代器使用问题——核心原因是**std::list的迭代器属于双向迭代器,而非随机访问迭代器**。双向迭代器只支持++/--这种单步移动操作,不允许用operator+(比如i + 1)直接跳跃到指定位置。而像std::vector、std::array这类容器的迭代器是随机访问迭代器,才支持直接做加法跳转。
修复代码的两种方式
方式1:用std::next获取下一个迭代器
C++标准库提供了std::next函数,专门用来安全获取迭代器的下一个位置,对双向迭代器完全适用:
#include <iostream> #include <algorithm> #include <list> #include <string> using namespace std; struct Ent { string name; Ent(const string& name) : name(name) { } bool operator== (const Ent& right) const { return name == right.name; } }; int main(int argc, char *argv[]) { list<Ent> l; for (char c = 'a'; c <= 'z'; c++) { Ent e(string(1, c)); l.push_back(e); } Ent e1("p"); typedef list<Ent>::const_iterator LI; LI i = find(l.begin(), l.end(), e1); int n = 0; while (i != l.end()) { ++n; // 替换i + 1为std::next(i) i = find(next(i), l.end(), e1); } cout << "find(" << e1.name << ") = " << n << endl; return 0; }
方式2:手动递增迭代器后传入
也可以先手动把迭代器往前挪一步,再传入find函数,逻辑和上面一致:
// 替换循环内的查找行 ++i; i = find(i, l.end(), e1);
更简洁的替代方案:直接用std::count
既然你的核心需求是统计匹配元素的出现次数,完全没必要自己写find循环,std::count可以直接完成这个任务,代码更简洁高效:
#include <iostream> #include <algorithm> #include <list> #include <string> using namespace std; struct Ent { string name; Ent(const string& name) : name(name) { } bool operator== (const Ent& right) const { return name == right.name; } }; int main(int argc, char *argv[]) { list<Ent> l; for (char c = 'a'; c <= 'z'; c++) { l.emplace_back(string(1, c)); // 用emplace_back直接构造对象,避免额外拷贝 } Ent e1("p"); int n = count(l.begin(), l.end(), e1); cout << "find(" << e1.name << ") = " << n << endl; return 0; }
内容的提问来源于stack exchange,提问作者user9405153
相关产品推荐
相关产品推荐

