C ++ Filtered с использованием ленивого итератора - PullRequest
1 голос
/ 09 января 2020
template<typename Iterator>
    struct Range {
        using LazyIterator = Iterator; // required for accessing the used Iterator type from other locations
        Iterator m_begin;
        Iterator m_end;
        auto begin() { return m_begin; }
        auto end() { return m_end; }
    };

    template<typename Iterator>
    Range(Iterator, Iterator) -> Range<Iterator>;    
 template<typename Iterator, typename Callable>
        struct FilteringIterator : Iterator {
            Callable callable;
            using OriginalIterator = Iterator;
            using t = typename OriginalIterator::value_type;
            FilteringIterator(const Iterator begin, Callable callable):Iterator(begin),callable(callable){}
            Iterator &get_orig_iter() { return ((Iterator &)*this); }
            auto operator*() { return callable(*get_orig_iter()); }
        };
auto filter = [](auto action) {
    return [=]( auto &container) {
        using Container = std::decay_t<decltype(container)>;
        using Iterator = typename Container::iterator;
        using actiontype = decltype(action);
        using filter_iterator = FilteringIterator<Iterator, actiontype>;
        return Range{filter_iterator{container.begin(),action}, filter_iterator{container.end(),action}};
    };
};

Мне нужен ленивый итератор, который будет проходить через диапазон и лениво фильтровать его. Например,

auto v = std::vector<double>{};
    auto odd_gen = views::odds();

    for(int i=0; i<5; ++i)
        v.push_back(odd_gen() * 2.5);
    // v contains {2.5, 7.5, 12.5, 17.5, 22.5} here

    new_line();
    for(auto a : v | filter(greater_than(15))) // filter is applied lazily as the range is traversed
        std::cout << a  << std::endl;
// print { 17.5, 22.5} here

, но он печатает

{0,0,0,0,17.5,22.5}

Я хочу, чтобы он печатал только 17,5, 22,5

как мне этого добиться?

1 Ответ

1 голос
/ 09 января 2020

Ваш код никогда не пропускает элементы, он просто преобразует их. Вы должны убедиться, что когда вызывается operator*(), он начинается с продвижения итератора, в то время как callable возвращает false, и только затем возвращает значение, на которое указывает Iterator.

. это угловые случаи, хотя вы должны позаботиться о. Если ввод заканчивается элементами, которые не соответствуют фильтру, вы сталкиваетесь с проблемой. Вам также нужно пропустить все отфильтрованные элементы при вызове operator++(). А также подумайте о случае, когда фильтр не будет соответствовать ни одному из элементов ввода; в этом случае вы должны убедиться, что begin() равно end().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...