Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прикладное программирование.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
439.97 Кб
Скачать

6.4. Объекты-функции. Предикаты

6.4.1. Объекты-функции. Пример 6.5 (использование объектов-функций)

Объекты-функции – это объекты, у которых перегружен оператор вызова функций operator(). В библиотеке STL уже определено несколько полезных арифметических и других объектов-функций (описание в файле <functional>):

  • plus сложение

  • minus вычитание

  • multipies умножение

  • divides деление

  • modulus деление по модулю

  • negate отрицание

Рассмотрим пример с отрицанием всех элементов вектора. Можно выполнить этот пример с помощью цикла, а можно сделать намного проще с использованием алгоритма transform и стандартной функции negate.

vector<int> v;

vector<int>::iterator it=v.begin();

while(it != v.end())

{

*it = -(*it);

it++;

}

// то же самое с использованием объекта-функции negate

transform(v.begin(),v.end(), v.begin(), negate<int>());

// вывод контейнера на экран

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

Алгоритмы (описание в файле < algorithm>) позволяют выполнять некоторые типовые действия надо контейнерами с использованием объектов-функций стандартной библиотеки или своих объектов-функций. Подробно алгоритмы, функции, и другие возможности библиотеки STL приводятся в Приложении 5.

Стандартные алгоритмы можно использовать и для ввода и вывод контейнера на экран. При чтении ввод происходит до ввода первого не числового символа.

Программисты могут определить свои объекты-функции, которые могут быть наследниками от стандартных. В объектах-функциях обязательно должен быть перегружен оператор вызова функции (), в конструкторе могут задаваться необходимые параметры, или он может быть пустым (см.пример 6.5).

Функции могут быть двух типов:

  • Унарная функция – это функция, в которой участвует один операнд (например, x=-y - унарный минуc)

  • Бинарная функция – это функция, в которой участвуют два операнда (например, x=y+z - сложение, умножение, и т.д.)

Для унарных функций перегруженный оператор вызова функции должен содержать один параметр, в бинарных – два параметра.

Иногда нужно преобразовать бинарную функцию в унарную, например умножение – бинарная функция, нужны два элемента, а мы хотим умножить все элементы контейнера на одно и то же число. Для этого можно использовать функцию bind2nd.

Функция binder2 nd – преобразует бинарную функцию в унарную, и принимает второй аргумент как параметр бинарной функции (описание в файле <functional>)

// умножение каждого элемента на 2

transform (v.begin(), v.end(), v.begin(), bind2nd(multiplies<int>(), 2));

Пример 6.5. Использование объектов-функций

/////////////////////////////////////////////////////////////////////////////

// Прикладное программирование

// Пример 6.5. Использование объектов-функций

//

// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru

// СПб НИУ ИТМО

/////////////////////////////////////////////////////////////////////////////

#include <functional>

#include <algorithm>

#include <vector>

#include <iostream>

#include <iterator>

using namespace std;

/////////////////////////////////////////////////////////////////////////////

// создание объекта-функции для заполнения случайными числами

// функция Rand - шаблон, наследник от стандартной функции unary_function

// параметры шаблона: PAR - тип данных, void - возвращаемое значение оператора ()

template <class PAR>

class Rand : public unary_function<PAR, void>

{

// диапазон случайных чисел

PAR m_min, m_max;

public:

// конструктор, в котором задается диапазон случайных чисел

Rand(PAR min, PAR max)

: m_min(min), m_max(max)

{ }

// перегруженный оператор вызова функции, в котором число value заполняется случайным числом

void operator() (PAR& value)

{

value=(PAR)(rand()*(m_max-m_min))/RAND_MAX+m_min;

}

};

/////////////////////////////////////////////////////////////////////////////

// тестирование объектов-функций STL - negate, ввод-вывод

void main()

{

vector<int> v;

// чтение контейнера из потока ввода (до первого не числового символа)

copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v));

// вывод контейнера на экран

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

cout<<endl;

// использование объекта-функции negate

transform(v.begin(),v.end(), v.begin(), negate<int>());

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

cout<<endl;

// заполнение контейнера случайными числами при помощи объекта-функции Rand

for_each(v.begin(), v.end(), Rand<int>(-10, 10));

copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));

cout<<endl;

// умножение каждого элемента на 2,

// использование стандартной бинарной функции multiplies,

// преобразованной в унарную при помощи функции bind2nd

transform (v.begin(), v.end(), v.begin(), bind2nd(multiplies<int>(), 2));

copy (v.begin(), v.end(),ostream_iterator<int>(cout, " "));

cout<<endl;

}

/////////////////////////////////////////////////////////////////////////////