На этом шаге мы рассмотрим использование адаптера compose_f_gx_hx.
Вероятно, из вспомогательных функциональных адаптеров самым важным является тот, который формирует единый критерий логическим объединением двух критериев. Он используется для формулировки условий типа "больше 4 и меньше 7".
Возможная реализация адаптера compose_f_gx_hx (в реализации SGI используется имя compose2) выглядит так:
#include <functional> // Класс композитного адаптера compose_f_gx_hx template <class OP1, class OP2, class OP3> class compose_f_gx_hx_t : public std::unary_function<typename OP2::argument_type, typename OP1::result_type> { private: OP1 op1; // Вычисление: op1(op2(x),op3(x)) OP2 op2; OP3 op3; public: // Конструктор compose_f_gx_hx_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // Вызов функции typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x),op3(x)); } }; // Вспомогательные функции для адаптера compose_f_gx_hx template <class OP1, class OP2, class OP3> inline compose_f_gx_hx_t<OP1,OP2,OP3> compose_f_gx_hx (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hx_t<OP1,OP2,OP3>(o1,o2,o3); }
Адаптер compose_f_gx_hx использует первую операцию для объединения результатов двух унарных операций с одним объектом. Следующее выражение создает унарный предикат:
compose_f_gx_hx(op1,ор2,ор3)
Этот предикат вычисляет для каждого значения х:
ор1(ор2(х),ор3(x))
Пример использования адаптера compose_f_gx_hx:
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <vector> #include <algorithm> #include <functional> #include "compose21.hpp" #include <conio.h> //необходимо для getch() #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused using namespace std; std::string ToRus(const std::string &in) { char *buff = new char [in.length()+1]; CharToOem(in.c_str(),buff); std::string out(buff); delete [] buff; return out; } template <class T> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << ToRus(optcstr); for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout <<*pos <<' '; } std::cout << std::endl; } int main() { vector<int> coll; // Вставка элементов со значениями от 1 до 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll,"Исходный вектор:\n"); // Удаление всех элементов, больших 4, но меньших 7 // - retain new end vector<int>::iterator pos; pos = remove_if (coll.begin(),coll.end(), compose_f_gx_hx(logical_and<bool>(), bind2nd(greater<int>(),4), bind2nd(less<int>(),7))); // Стирание "удаленных" элементов из коллекции coll.erase(pos,coll.end()); PRINT_ELEMENTS(coll,"Вектор после изменения:\n"); getch(); return 0; } //---------------------------------------------------------------------------
Следующее выражение формирует унарный предикат для проверки условия "значение больше 4 и меньше 7":
compose_f_gx_hx(logical_and<bool>(), bind2nd(greater<int>(),4), bind2nd(less<int>(),7)));
Результат выполнения программы выглядит так:
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим бинарные композиционные адаптеры.