function objects and predicates in STL algorithms
function objects and predicates define function objects:
classes that overload function invocation operators, whose objects are often called function objects, are objects that behave like functions. A class object that shows the characteristics of a function that is through the object name + (
Parameter list) "uses a class object in a way that can be treated as a function if there is no context.
This is done by overloading the operator () of the class.
"In the standard library, function objects are widely used for elasticity," and many of the algorithms in the standard library can use function objects or functions as self-defined callback behaviors .
Unary function object: function parameter one;
Binary function object: 2 function parameters;
Predicate:
A predicate is a function that returns a value of type bool because the function object is a type of object that implements the operator () () member function and returns a value of type bool, so the function object is also a predicate.
A predicate can be an imitation function or a callback function .
Unary predicate function parameter 1, function return value is bool type
Binary predicate function parameter 2, function return value is bool type
An example of a unary predicate function is as follows
1, determines whether the given string object is less than 6 length
BOOL GT6 (const string &s)
{
Return S.size () >= 6;
}
2, determine whether the given int is between 3 and 8
BOOL Compare (int i)
{
Return (i >= 3 && i <= 8);
}
Examples of binary predicates are as follows
1, compares two string objects, returns a bool value indicating whether the first string is shorter than the second
BOOL Isshorter (const string &S1, const string &s2)
{
Return S1.size () < S2.size ();
}
Unary function Object case
1 General class overloaded function call operator
Template <typename t>
void Funcshowelemt (T &t)//normal function cannot record state like an imitation function
{
cout << t << "";
};
void Showchar (char &t)
{
cout << t << "";
}
function template overloaded function call operator
Template <typename t>
Class Showelemt
{
Public
SHOWELEMT ()
{
n = 0;
}
void operator () (T &t)
{
n++;
cout << t << "";
}
void PrintCount ()
{
cout << n << Endl;
}
Public
int n;
};
1 Basic use of Function objects
void Main ()
{
int a = 100;
Funcshowelemt<int> (a); normal function calls
Showelemt<int> showelemt; Function object
SHOWELEMT (a); Function Object Invocation
}
unary predicate case
1 USD Predicate example
Template <typename t>
Class Isdiv
{
Public
Isdiv (const T &divisor)//
{
This->divisor = divisor;
}
BOOL Operator () (T &t)
{
return (T%divisor = = 0);
}
Protected
Private
T Divisor;
};
void Main ()
{
Vector<int> v2;
for (int i=10; i<33; i++)
{
V2.push_back (i);
}
Vector<int>::iterator it;
int a = 4;
Isdiv<int> Mydiv (a);
_init find_if (_init _first, _init _last, _PR _pred)//return iterator
it = find_if (V2.begin (), V2.end (), isdiv<int> (4));
if (It! = V2.end ())
{
cout << "The first number divisible by 4 is:" << *it << Endl;
}
}
Binary Function Object case
Template <typename t>
struct SUMADD
{
T operator () (t &t1, T &T2)
{
return t1 + T2;
}
};
Template <typename t>
void Printe (T &t)
{
for (Vector<int>::iterator it = T.begin (); It!=t.end (); it++)
{
cout << *it << "";
}
}
void Printvector (vector<int> &v)
{
for (Vector<int>::iterator it = V.begin (); It!=v.end (); it++)
{
cout << *it << "";
}
}
void Main ()
{
Vector<int> v1, v2;
Vector<int> v3;
V1.push_back (1);
V1.push_back (2);
V1.push_back (3);
V2.push_back (4);
V2.push_back (5);
V2.push_back (6);
V3.resize (10);
Transform (V1.begin (), V1.end (), V2.begin (), V3.begin (), sumadd<int> ());
/*
Template<class _init1, Class _init2, Class _outit, class _fn2> inline _outit transform (_init1 _first1, _init1 _last1 , _init2 _first2, _outit _dest, _fn2 _func)
*/
Vector<int>::iterator it = transform (V1.begin (), V1.end (), V2.begin (), V3.begin (), sumadd<int> ());
cout << *it << Endl;
Printe (v3);
}
Binary predicate case
void current (int &v)
{
cout << v << "";
}
BOOL Mycompare (const int &A, const int &b)
{
return a < b;
}
void Main ()
{
Vector<int> V (10);
for (int i=0; i<10; i++)
{
V[i] = rand ()% 100;
}
For_each (V.begin (), V.end (), current);
printf ("\ n"); Sort (V.begin (), V.end (), mycompare);
printf ("\ n");
for (int i=0; i<10; i++)
{
printf ("%d", v[i]);
}
printf ("\ n");
}
predefined function objects and function adapters
1)Basic concepts of pre-defined function objects: The standard Template Library STL defines many predefined function objects in advance.
#include <functional> must be included.
1 Using predefined function objects:
The implementation of class template plus<>: Different types of data for addition operations
void Main ()
{
Plus<int> Intadd;
int x = 10;
int y = 20;
int z = intadd (x, y); Equivalent to X + y
cout << z << endl;
Plus<string> Stringadd;
String Myc = Stringadd ("AAA", "BBB");
cout << Myc << Endl;
Vector<string> v1; V1.push_back ("BBB");
V1.push_back ("AAA");
V1.push_back ("CCC");
V1.push_back ("zzzz");
By default, sort () arranges the elements of the container with less than the operation ascending of the underlying element type.
In order to be descending, you can pass a predefined class template greater, which invokes the greater-than operator of the underlying element type:
cout << "sort () function" << Endl;
Sort (V1.begin (), V1.end (), greater<string> ()); From big to small
For (Vector<string>::iterator It=v1.begin (); It!=v1.end (); it++)
{
cout << *it << Endl;
}
}
2) The function object predefined by the arithmetic function object supports addition, subtraction, multiplication, addition, redundancy, and negation. The invoked operator is an instance associated with type
Addition:plus<types>
Plus<string> Stringadd;
Sres = Stringadd (SVA1,SVA2);
Subtraction:minus<types>
Multiplication:multiplies<types>
Division Divides<tpye>
Yu:modulus<tpye>
Take the anti-:negate<type> negate<int> intnegate;
Ires = Intnegate (IRES);
Ires= Unaryfunc (negate<int> (), Ival1);
3) Relational Function object
equals equal_to<tpye>
Equal_to<string> stringequal;
Sres = Stringequal (SVAL1,SVAL2);
Not equal to not_equal_to<type>
Greater than greater<type>
Greater than or equal to greater_equal<type>
Less than less<type>
Less than or equal to less_equal<type>
void Main ()
{
Vector<string> v1;
V1.push_back ("BBB");
V1.push_back ("AAA");
V1.push_back ("CCC");
V1.push_back ("zzzz");
V1.push_back ("CCC");
string S1 = "CCC";
int num = count_if (V1.begin (), V1.end (), equal_to<string> (), S1);
int num = count_if (V1.begin (), V1.end (), bind2nd (Equal_to<string> (), S1));
cout << num << endl;
}
4) Logical Function object
Logic and Logical_and<type>
Logical_and<int> Indand;
Ires = Intand (IVAL1,IVAL2);
Dres=binaryfunc (Logical_and<double> (), dval1,dval2);
Logical OR Logical_or<type>
Logical non-logical_not<type>
Logical_not<int> Intnot;
Ires = Intnot (IVAL1);
Dres=unaryfunc (LOGICAL_NOT<DOUBLE>,DVAL1);
function Adapter
There are three types of adapters in C + +, the container adapter, the iterator adapter, and the function adapter, which mainly describes the function adapter.
1) Theoretical knowledge of function adapters
2) common function function Adapter
The standard library provides a set of function adapters that specialize or extend a unary and two-tuple function object.
Common adapters are:
1 Binder (Binder): Binders Convert a $ two function object to a unary function object by binding an argument to a special value. The C + + standard library provides two predefined binder adapters: bind1st and bind2nd, which bind values to the first argument of a two-tuple function object, which is bound on the second argument.
2 Counter (negator): Negator is a function adapter that flips the value of a function object.
The standard library provides two pre-defined Ngeator adapters:
NOT1 flips the true value of a unary predefined function object, while Not2 flips the truth value of a two-tuple predicate function.
A list of commonly used function adapters is as follows:
bind1st (OP, value)
bind2nd (OP, value)
Not1 (OP)
Not2 (OP)
Mem_fun_ref (OP)
Mem_fun (OP)
Ptr_fun (OP)
3) Common function adapter case
//////////////////////////////////////////////////////////////////////////
Class Isgreat
{
Public
isgreat (int i)
{
M_num = i;
}
BOOL operator () (int &num)
{
if (num > M_num)
{
return true;
}
return false;
}
Protected
Private
int m_num;
};
void Main ()
{
Vector<int> v1;
for (int i=0; i<5; i++)
{
V1.push_back (i+1);
}
for (Vector<int>::iterator it = V1.begin (); It!=v1.end (); it + +)
{
cout << *it << ""
}
int NUM1 = count (V1.begin (), V1.end (), 3);
cout << "NUM1:" << num1 << Endl;
The number of more than 2 is evaluated by the predicate
int num2 = count_if (V1.begin (), V1.end (), Isgreat (2));
cout << "num2:" << num2 << Endl;
The number of greater<int> () that is greater than 2 is calculated by using a predefined function object with 2 parameters
param > 2
int num3 = count_if (V1.begin (), V1.end (), bind2nd (Greater<int> (), 2));
cout << "num3:" << num3 << Endl;
The modulus can be divisible by 2 for odd numbers.
int num4 = count_if (V1.begin (), V1.end (), bind2nd (modulus <int> (), 2));
cout << "Odd num4:" << num4 << Endl;
int NUM5 = count_if (V1.begin (), V1.end (), Not1 (bind2nd (modulus <int> (), 2)));
cout << "Even num5:" << num5 << Endl;
Return
}
function objects and predicates in STL algorithms