STL алгоритмы: for_each_if
От: lomezych  
Дата: 09.02.04 13:50
Оценка:
Значить так.

Имеется абстрактный базовый класс.
class Foo 
{
public:
// ...    
    virtual bar mf(int) = 0;
// ...
    virtual void generator() = 0;
// ...
}

Потом создаётся много-много производных... и все они живут в
std::vector<Foo*> sequence;

Также имеетя некий manager, который делает с этим вектором много чего.

Хотелось бы выполнения функции в for_each(...) при каком-то условии. Написали for_each_if.
template <class InputIterator, class Predicate, class Function>
void for_each_if( InputIterator first, InputIterator last, Function f, Predicate pred )
{
    while ( first != last ) { 
        if ( pred( *first ) )
            f( *first++ ); 
        else
            first++;
    }
}

Тааакс.. на чём мы значит остановились.. ааа даа... Понадобился мне, значить, предикат, чтобы делал проверку на range. Окей... тоже написали:
template <class T> class in_range
    : public std::unary_function<T, bool> 
{
    T min;
    T max;

public:
    explicit in_range(const T& _min, const T& _max) : min(_min), max(_max) { }
    bool operator()( const T& val ) const { return ( val >= min && val <= max); }
};

Значить, тапереча, если у нас будет
std::vector<int> seq;

то можна найти, допустим, первое число в диапазоне (min...max)
std::vector<int>::iterator res = find_if(seq.begin(),
                                         seq.end(), 
                                         in_range<int>(min,max)
                                        );

Есть и другая запись, собсна, того же действа,
std::vector<int>::iterator res = find_if(seq.begin(),
                                         seq.end(),
                                         compose2(logical_and<bool>(),
                                                  bind2nd(greater_equal<int>(), min),
                                                  bind2nd(less_equal<int>(), max)
                                                 )
                                        );

но адаптер compose2 не является частью стандарта так что остаётся 1ый вариант... на худой конец можно выдрать код из какого-нть SGI STL.

Значит в чём загвоздка. Хотелось бы на месте mim и max увидеть значения, возвращаемые Foo::mf(int).
Те что-то типа:
for_each_if(sequence.begin(), sequence.end(), mem_fun(&Foo::generator), in_range<bar>(Foo::mf(1), Foo::mf(2)));
// тока не бейте!! :))  это так... чтоб ход мыслей продемонстрировать...

На данный момент имеется несколько специализаций для in_range, заточенных под vector<Foo*>,
но если их число будет расти это не есть хорошо. Хотелось бы какого-нть более универсального подхода.

Жду советов и коментов!
... << RSDN@Home 1.1.3 beta 1 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.