Шаг 250.
Библиотека STL. Объекты функций STL. Унарные композиционные адаптеры. Вложенные вычисления с использованием адаптера compose_f_gx

    На этом шаге мы рассмотрим использование адаптера compose_f_gx.

    Унарные композиционные адаптеры являются весьма важными. Они также входят в реализацию STL от SGI.

Вложенные вычисления с использованием адаптера compose_f_gx

    В простейшем композиционном адаптере результаты выполнения одной унарной операции становятся входными данными для другой унарной операции. Иначе говоря, этот адаптер просто обеспечивает вложенный вызов двух унарных объектов функций. Он понадобится для формулировки условий типа "прибавить 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.




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