Стандартные функторы stl
Стандартная библиотека содержит большое количество стандартных функторов, которые могут быть использованы вместе с алгоритмами, а также вспомогательные функторы, с помощью которых можно комбинировать более простые, а также модифицировать их поведение.
Арифметические выражения
Стандартная библиотека содержит ряд функторов соответствующих арифметическим операциям.
// сложение, возвращает x+y
// для типа Tтребует перегруженного оператораoperator+
template<classT>
struct plus : binary_function<T, T, T>
{
Т operator()(const T& x, const T& y) const;
};
// вычитание, возвращает x-y
// для типа Tтребует перегруженного оператораoperator-
template<class T>
struct minus : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const;
};
// умножение, возвращает x*y
// для типа Tтребует перегруженного оператораoperator*
template<class T>
struct multiplies : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const;
};
// деление, возвращает x/y
// для типа Tтребует перегруженного оператораoperator/
template<class T>
struct divides : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const;
};
// остаток от деления, возвращает x%y
// для типа Tтребует перегруженного оператораoperator%
template<class T>
struct modulus : binary_function<T, T, T>
{
T operator()(const T& x, const T& y) const;
};
// унарный минус, возвращает - x
// для типа Tтребует перегруженного оператораoperator-
template<class T>
struct negate : unary_function<T, T>
{
T operator()(const T& x) const;
};
Для вычисления результата каждый из функторов использует соответствующий оператор, так функтор plusиспользует для вычисления результатoperator+, другими словами, для использования одного из арифметических функторов с каким-либо пользовательским типом необходимо, чтобы для этого типа был определен соответствующий арифметический оператор. Если соответствующий оператор не будет определен (будет существовать встроенная версия или перегруженная пользователем) для типа, к которому применяется компилятор выдаст ошибку примерно следующего содержания«binary '+' : 'const class Type' does not define this operator or a conversion to a type acceptable to the predefined operator».
Обратим внимание на параметры шаблонов всех арифметических функторов, типы обоих аргументов совпадают, а также совпадают с типом возвращаемого значения. Следовательно, функторы должны применятся к аргументам одного типа или в случае разных типов должно существовать преобразование одного из аргументов к типу другого.
Ниже приведен пример использования функтора plus.Представим себе следующую задачу: необходимо сложить два комплексных вектора (для простоты с целыми действительной и мнимой частями) и результат записать в первый вектор, а потом изменить знак чисел в этом векторе. Вот очень простой пример реализации
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
class Complex
{
public:
Complex (int a, int b):
Re (a), Im (b)
{};
Complex operator+(const Complex& Second) const
{
int fResult = Re + Second.Re;
int sResult = Im + Second.Im;
return (Complex (fResult, sResult));
};
Complex operator- () const
{
return (Complex (-Re, -Im));
};
private:
int Re,Im;
friend void print (const Complex& Source);
};
void print (const Complex& Source)
{
cout << Source.Re << " + " << Source.Im << "i" << endl;
};
int main (int, char**)
{
Complex A (1, 1); // A = 1 + i
Complex B (2, 2); // B = 2 + 2i
Complex C (3, 3); // C = 3 + 3i
vector<Complex> fArray;
fArray.push_back (A);
fArray.push_back (B);
vector<Complex> sArray;
sArray.push_back (B);
sArray.push_back (C);
// Сложить вектора
transform (fArray.begin(), fArray.end(),
sArray.begin(),
fArray.begin(),
plus<Complex> ());
// Изменить знак у результата
transform (fArray.begin(), fArray.end(),
fArray.begin(),
negate<Complex> ());
for_each(fArray.begin (), fArray.end (), print);
return 0;
}
Вывод программы:
-3 + -3i
-5 + -5i