如何实现迭代器包装类以解引用std::map中存储的指针适配范围for循环
实现方案说明
核心问题分析
你遇到的核心问题是:operator*不能直接返回绑定到临时std::pair的左值引用,会导致悬空引用的未定义行为。同时需要兼顾三种使用场景的访问权限控制。
具体实现修改
我们不需要额外存储解引用后的元素,直接返回包含引用的std::pair右值即可满足需求,同时适配C++11及以上标准。完整可运行代码如下:
#include <map> #include <array> #include <utility> using HT = std::map<int, int*>; class ITERATOR_PROXY { public: ITERATOR_PROXY(HT& container) : m_container(container) { } // 非const版本迭代器,支持修改值 auto begin() { return HT_ITERATOR_WRAPPER(std::begin(m_container)); } auto end() { return HT_ITERATOR_WRAPPER(std::end(m_container)); } // const版本迭代器,禁止修改值 auto begin() const { return HT_CONST_ITERATOR_WRAPPER(std::cbegin(m_container)); } auto end() const { return HT_CONST_ITERATOR_WRAPPER(std::cend(m_container)); } private: // 非const迭代器包装 struct HT_ITERATOR_WRAPPER { HT_ITERATOR_WRAPPER(HT::iterator iter_) : iter(iter_) {} bool operator!=(const HT_ITERATOR_WRAPPER& other) const { return iter != other.iter; } // 返回包含引用的pair右值,无需额外存储成员 std::pair<const int&, int&> operator*() { return {iter->first, *iter->second}; } void operator++() { ++iter; } HT::iterator iter; }; // const迭代器包装 struct HT_CONST_ITERATOR_WRAPPER { HT_CONST_ITERATOR_WRAPPER(HT::const_iterator iter_) : iter(iter_) {} bool operator!=(const HT_CONST_ITERATOR_WRAPPER& other) const { return iter != other.iter; } std::pair<const int&, const int&> operator*() const { return {iter->first, *iter->second}; } void operator++() { ++iter; } HT::const_iterator iter; }; HT& m_container; }; int main() { HT ht; std::array<int, 5> val = {0,1,2,3,4}; for (int i = 0; i < 5; ++i) ht[i] = &val[i]; ITERATOR_PROXY htw(ht); // 场景1:值捕获,修改不影响原数组 for(auto x : htw) { x.second += 100; // 仅修改副本,val数组不变 } // 场景2:右值引用捕获,可修改原数组 for(auto&& x : htw) { x.second += 100; // 直接修改val数组元素 } // 场景3:const引用捕获,修改触发编译错误 for(const auto& x : htw) { // x.second += 100; // 取消注释会编译报错,x.second是const int&不可修改 } }
场景适配说明
- 值捕获
auto x:std::pair的拷贝构造会对引用成员执行取值拷贝,得到的x是独立的std::pair<const int, int>副本,修改x.second不会影响原数组。 - 右值引用捕获
auto&& x:x绑定到operator*返回的临时pair,x.second是指向原数组元素的int&,修改直接作用到原数组。如果一定要用auto&语法,可以自定义代理结构体存储指针,每次迭代更新指针指向后返回左值引用即可。 - const引用捕获
const auto& x:临时pair被const引用绑定,x.second是const int&,尝试修改会直接触发编译错误。
内容的提问来源于stack exchange,提问作者g2006
相关产品推荐
相关产品推荐

