如何让auto类型推导适配基于范围的for循环以得到迭代器类型?
问题解析与解决方法
为什么auto推导的r是int类型?
基于范围的for循环的底层逻辑很明确:
- 先调用
range::begin()和range::end()获取迭代器对象 - 循环过程中,每次对迭代器执行
*it解引用操作,把解引用的结果赋值给循环变量r - 你的
range_iterator::operator*()返回的是int类型,所以auto自然推导出int
简单说:范围for的循环变量存储的是迭代器指向的元素值,不是迭代器本身,这就是它和begin()/end()返回类型不同的原因。
如何让auto推导出range_iterator类型?
如果你想让循环变量直接是迭代器本身,有两种实用思路:
思路1:直接使用普通for循环(最直观)
放弃范围for,手动写迭代器遍历的循环,这样循环变量天然就是迭代器类型:
int main() { range r0; for (auto it = r0.begin(); it != r0.end(); ++it) { // it 就是 range_iterator 类型,可直接操作 } return 0; }
思路2:包装迭代器为"元素"(硬套范围for的方案)
如果非要用范围for,需要创建一个特殊的"范围类",让它的元素就是迭代器本身。比如自定义一个简单的包装:
// 包装迭代器的范围类 template <typename Iter> struct IteratorRange { Iter start; Iter finish; // 自定义内部迭代器,用来指向包装里的迭代器 struct InnerIter { Iter* ptr; Iter& operator*() const { return *ptr; } InnerIter& operator++() { ++ptr; return *this; } bool operator!=(const InnerIter& other) const { return ptr != other.ptr; } }; InnerIter begin() const { return {&start}; } InnerIter end() const { return {&finish}; } }; int main() { range r0; IteratorRange iter_range{r0.begin(), r0.end()}; for (auto it : iter_range) { // it 现在是 range_iterator 类型 } return 0; }
不过这种包装属于刻意适配,实际开发中如果需要操作迭代器,普通for循环更简洁直接。
内容的提问来源于stack exchange,提问作者Xie Qing
相关产品推荐
相关产品推荐

