2011-04-16 2 views
11

У меня есть последовательность значений, которые я хотел бы передать функции, которая принимает пару (iterator begin, iterator end). Тем не менее, я хочу, чтобы каждый второй элемент в исходной последовательности обрабатывался.Пропуская итератор

Есть ли хороший способ использовать стандарт-Lib/Boost для создания фасада итератора, который позволит мне пройти в исходной последовательности? Я понял, что что-то простое, как это было бы уже в итераторах повышения или библиотеках диапазонов, но я ничего не нашел.

Или я пропустил еще один совершенно очевидный способ сделать это? Конечно, я знаю, что у меня всегда есть возможность копировать значения в другую последовательность, но это не то, что я хочу сделать.

Редактировать: Я знаю о filter_iterator, но что фильтры по значениям - это не меняет способ продвижения итерации.

+0

Ia задал несколько другой вопрос по одному и тому же вопросу: http://stackoverflow.com/questions/3046747/c-stl-selective-iterator, bt Я специально запросил no Boost, не очень полезный тогда :( – rubenvb

ответ

2

Вот Boost's filter iterator. Это именно то, что вы хотите.

ОБНОВЛЕНИЕ: Извините, прочитайте неправильно. Вот список все итератора funkiness в НЧ:

http://www.boost.org/doc/libs/1_46_1/libs/iterator/doc/#specialized-adaptors

Я думаю, простой iterator_adaptor с перегруженной operator++, что приращение стоимости базового итератора в два раза все, что вам нужно.

+0

Нет, это не. Итератор фильтра фильтрует последовательности с предикатом на значениях - но я хотел бы иметь предикат на итераторе (если вы хотите подумать об этом как об фильтрации вообще). В принципе, я просто хочу представить '+ = 2' как' ++ 'моему внутреннему оператору – ltjax

+0

, проблема в том, что применение (в реализации) оператора ++ дважды может пропустить конец контейнера, не проверяя, был ли пропущенный элемент уже завершен () итератор. Althogh У меня есть цикл for for (skip_iterator it = v.begin(); it! = V.end(); ++ it) {} – alfC

+2

alfC: Вам нужно будет проверить, '' it! = End' внутри 'operator ++', перед вторым вызовом 'operator ++ '. – rubenvb

3
struct TrueOnEven { 
template< typename T > 
bool operator()(const T&) { return mCount++ % 2 == 0; } 
TrueOnEven() : mCount(0) {} 
private: 
    int mCount; 
}; 

int main() { 
std::vector<int> tVec, tOtherVec; 
... 
typedef boost::filter_iterator< TrueOnEven, int > TakeEvenFilterType; 

std::copy( 
    TakeEvenFilterType(tVec.begin(), tVec.end()), 
    TakeEvenFilterType(tVec.end(), tVec.end()), 
    std::back_inserter(tOtherVec)); 
} 

Если честно, это ничего, кроме приятного и интуитивно понятного. Я написал простую «Enumerator» библиотеку, включая ленивые интегрированные запросы, чтобы избежать мешанин, как выше .. Это позволяет написать:

Query::From(tVec.begin(), tVec.end()) 
.Skip<2>() 
.ToStlSequence(std::back_inserter(tOtherVec)); 

где Skip<2> основном конкретизирует обобщенный «фильтр», который пропускает каждый N-й (в в этом случае каждый второй) элемент ...

Cheers,

Пол

+0

+1 за то, что он признал, что это просто глупый взлом. Он также делает много предположений о том, как внутренний алгоритм использует итератор и как 'filter_iterator' использует предикат.Например, если 'operator()' дважды оценивается для заданного итератора, все выходит из строя. – ltjax

+0

Ну, строго говоря, если filter_iterator классифицируется ничем иным, как 'std :: input_iterator' или' boost :: SinglePass'. Вероятно, вы должны написать полноценный 'skipping_iterator', который сложнее, чем может показаться ... –

Смежные вопросы