You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中实现统一的过滤器迭代器?

实现带过滤功能的自定义迭代器

原代码的问题

  • 错误地同时继承STL迭代器并维护独立的iter成员,导致迭代器状态不一致,比如调用++时基类迭代器和成员iter的位置不同步。
  • 构造函数未接收过滤函数对象,func未初始化,运行时会触发未定义行为。
  • operator*的逻辑错误:只是在元素不符合条件时返回空格,而非跳过该元素,无法实现过滤遍历的需求。

正确实现方案

自定义过滤迭代器的核心是封装原迭代器,而非继承,同时在迭代过程中自动跳过不符合过滤规则的元素。需要实现迭代器的必要接口,包括关联类型、递增运算符、比较运算符以及解引用运算符。

完整实现代码

#include <iostream>
#include <vector>
#include <iterator>
#include <functional>

template <class Iter, class FilterFunction>
class FilterIterator {
public:
    // 定义迭代器关联类型,兼容STL迭代器要求
    using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
    using value_type = typename std::iterator_traits<Iter>::value_type;
    using difference_type = typename std::iterator_traits<Iter>::difference_type;
    using pointer = typename std::iterator_traits<Iter>::pointer;
    using reference = typename std::iterator_traits<Iter>::reference;

    // 构造函数:接收起始迭代器、结束迭代器、过滤函数
    FilterIterator(Iter begin, Iter end, FilterFunction func)
        : current_(begin), end_(end), filter_(std::move(func)) {
        // 初始化时定位到第一个符合条件的元素
        skip_invalid();
    }

    // 前置递增运算符:跳过不符合条件的元素
    FilterIterator& operator++() {
        ++current_;
        skip_invalid();
        return *this;
    }

    // 后置递增运算符
    FilterIterator operator++(int) {
        FilterIterator temp = *this;
        ++current_;
        skip_invalid();
        return temp;
    }

    // 解引用运算符
    reference operator*() const {
        return *current_;
    }

    // 指针访问运算符
    pointer operator->() const {
        return &(*current_);
    }

    // 相等比较
    bool operator==(const FilterIterator& other) const {
        return current_ == other.current_;
    }

    // 不等比较
    bool operator!=(const FilterIterator& other) const {
        return !(*this == other);
    }

private:
    Iter current_;
    Iter end_;
    FilterFunction filter_;

    // 跳过所有不符合过滤条件的元素
    void skip_invalid() {
        while (current_ != end_ && !filter_(*current_)) {
            ++current_;
        }
    }
};

// 辅助函数:简化FilterIterator的创建
template <class Iter, class FilterFunction>
FilterIterator<Iter, FilterFunction> make_filter_iterator(Iter begin, Iter end, FilterFunction func) {
    return FilterIterator<Iter, FilterFunction>(begin, end, std::move(func));
}

// 测试用的过滤函数对象:判断偶数
class IsEven {
public:
    bool operator()(int num) const {
        return num % 2 == 0;
    }
};

int main() {
    std::vector<int> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 创建过滤迭代器,只遍历偶数
    auto begin = make_filter_iterator(vec.begin(), vec.end(), IsEven());
    auto end = make_filter_iterator(vec.end(), vec.end(), IsEven());

    for (auto iter = begin; iter != end; ++iter) {
        std::cout << *iter << std::endl;
    }

    // 也可以用lambda表达式作为过滤规则
    std::cout << "\n过滤大于5的元素:" << std::endl;
    auto lambda_begin = make_filter_iterator(vec.begin(), vec.end(), [](int num) {
        return num > 5;
    });
    auto lambda_end = make_filter_iterator(vec.end(), vec.end(), [](int num) {
        return num > 5;
    });
    for (auto iter = lambda_begin; iter != lambda_end; ++iter) {
        std::cout << *iter << std::endl;
    }

    return 0;
}

关键实现说明

  1. 迭代器关联类型:通过std::iterator_traits获取原迭代器的类型信息,确保自定义迭代器兼容STL的迭代器范畴(比如随机访问、双向等)。
  2. 构造函数与初始化:构造时直接定位到第一个符合过滤条件的元素,避免第一次解引用时得到无效元素。
  3. 递增逻辑:每次递增后调用skip_invalid()自动跳过不符合条件的元素,直到找到有效元素或到达容器末尾。
  4. 封装而非继承:避免了继承STL迭代器带来的状态不一致问题,同时适配所有类型的STL迭代器(包括指针类型的迭代器)。
  5. 辅助函数make_filter_iterator:简化迭代器的创建,无需手动指定模板参数。

内容的提问来源于stack exchange,提问作者zrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:15:33