STL list包装类如何同时暴露iterator与const_iterator支持范围for循环
错误原因
- C++ 成员函数的重载规则要求参数列表(包括隐含的this指针修饰符)必须有差异,仅返回值类型不同无法构成合法重载。你写的两个
begin()、两个end()都是无参的非const成员函数,只有返回值分别是const_iterator和iterator,不符合重载要求,因此编译报错。 - 代码还存在笔误:类成员变量命名为
_list,但begin()/end()实现中错误调用了不存在的变量l的方法。
修复方案
给返回const_iterator的begin()、end()添加const修饰符,让它成为const成员函数,这样就和非const版本的成员函数形成了合法重载,编译器会根据调用对象的const属性自动匹配对应版本,也能完美支持两种范围for写法。
修改后的完整代码如下:
#include <list> using std::list; template <typename T> class list_wrapper { public: list<T> _list; // const 成员函数,返回const_iterator,供const对象/只读场景调用 typename list<T>::const_iterator begin() const { return _list.begin(); } typename list<T>::const_iterator end() const { return _list.end(); } // 非const成员函数,返回iterator,供非const对象/修改场景调用 typename list<T>::iterator begin() { return _list.begin(); } typename list<T>::iterator end() { return _list.end(); } // 可选:补充显式的cbegin/cend,方便主动要求只读迭代器 typename list<T>::const_iterator cbegin() const { return _list.cbegin(); } typename list<T>::const_iterator cend() const { return _list.cend(); } }; int main(int argc, char** argv) { list_wrapper<int> myList; myList._list.push_back(1); myList._list.push_back(2); // 自动匹配非const版本,返回iterator,支持修改元素 for (auto& i : myList) { i *= 2; } // 自动匹配const版本,返回const_iterator,只读不可修改 for (const auto& i : myList) { // 这里i是只读的,修改会报错 } // 显式用const对象调用也会匹配const版本 const list_wrapper<int>& const_myList = myList; for (const auto& i : const_myList) { // 只读 } return 0; }
补充说明
如果只保留const版本的begin()/end(),那么所有场景下都只能拿到const_iterator,无法修改元素;如果只保留非const版本,那么const修饰的list_wrapper对象就无法调用迭代器方法,两种写法都保留才能覆盖全场景。
内容的提问来源于stack exchange,提问作者basil
相关产品推荐
相关产品推荐

