Шаг 251.
Библиотека STL. Объекты функций STL. Унарные композиционные адаптеры. Объединение двух критериев с использованием адаптера compose_f_gx_hx

    На этом шаге мы рассмотрим использование адаптера 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. Результат работы приложения

    На следующем шаге мы рассмотрим бинарные композиционные адаптеры.




Предыдущий шаг Содержание Следующий шаг