На этом шаге мы рассмотрим использование адаптера compose_f_gx.
Унарные композиционные адаптеры являются весьма важными. Они также входят в реализацию STL от SGI.
В простейшем композиционном адаптере результаты выполнения одной унарной операции становятся входными данными для другой унарной операции. Иначе говоря, этот адаптер просто обеспечивает вложенный вызов двух унарных объектов функций. Он понадобится для формулировки условий типа "прибавить 10 и умножить на 4".
Возможная реализация адаптера compose_f_gx (в реализации SGI используется имя compose1) выглядит так:
#include <functional> // Класс композиционного адаптера compose_f_gx template <class OP1, class OP2> class compose_f_gx_t : public std::unary_function<typename OP2::argument_type, typename OP1::result_type> { private: OP1 op1; // Вычисление: op1(op2(x)) OP2 op2; public: // Конструктор compose_f_gx_t(const OP1& o1, const OP2& o2) : op1(o1), op2(o2) { } // Вызов функции typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x)); } }; // Вспомогательные функции для адаптера compose_f_gx template <class OP1, class OP2> inline compose_f_gx_t<OP1,OP2> compose_f_gx (const OP1& o1, const OP2& o2) { return compose_f_gx_t<OP1,OP2>(o1,o2); }
Пример использования адаптера compose_f_gx:
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <vector> #include <algorithm> #include <functional> #include "compose11.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"); // Для каждого элемента прибавить 10 и умножить на 5 cout << ToRus("Вектор после изменения:\n"); transform (coll.begin(),coll.end(), ostream_iterator<int>(cout," "), compose_f_gx(bind2nd(multiplies<int>(),5), bind2nd(plus<int>(),10))); cout << endl; getch(); return 0; } //---------------------------------------------------------------------------
Обратите внимание: сначала выполняется вторая операция, переданная compose_f_gx. Таким образом, следующая конструкция создает унарный объект функции, который сначала прибавляет 10, а потом умножает результат на 5:
compose_f_gx(bind2nd(multiplies<int>(),5), bind2nd(plus<int>(),10)));
Результат выполнения программы:
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим использование адаптера compose_f_gx_hx.