[C + + improve programming] 4 STL - function object

1. Function object

Concept:

  • A class that overloads the function call operator. Its object is often called a function object
  • When a function object uses overloaded (), its behavior is similar to that of a function call, which is also called an imitation function

Essence:

  • A function object is a class, not a function

Features of function objects:

  • When a function object is used, it can be called like an ordinary function, with parameters and return values
class MyAdd
{
public:
	int operator()(int v1, int v2)
    {
        return v1 + v2;
    }
};

void test01()
{
    MyAdd myAdd;
    cout << myAdd(10, 10) << endl;
}
  • Function objects go beyond the concept of ordinary functions. Function objects can have their own states
class MyPrint
{
public:
    MyPrint()
    {
        this->count = 0;
    }
    void operator()(string test)
    {
        cout << test << endl;
        this->count++;//Count usage times
    }

    int count;//Internal self state
};

void test01()
{
    MyPrint myPrint;
    myPrint("Hello!");
    cout << "myPrint Number of calls:" << myPrint.count << endl;
}
  • Function objects can be passed as arguments
class MyPrint
{
public:
    MyPrint()
    {
        this->count = 0;
    }
    void operator()(string test)
    {
        cout << test << endl;
        this->count++;
    }

    int count;//The internal state can record the number of calls
};

void doPrint(MyPrint& mp, string test)
{
    mp(test);
}

void test01()
{
    MyPrint myPrint;
    doPrint(myPrint, "Hello");
}

The imitation function is very flexible and can be passed as a parameter

2. Predicate

2.1 predicate concept

  • The functor that returns bool type becomes a predicate
  • If operator() accepts a parameter, it is called a unary predicate
  • If operator() accepts two parameters, it is called a binary predicate

2.2 unary predicate

#include<vector>
#include<algorithm>

class GreaterFiver
{
public:
    bool operator()(int val)
    {
        return val > 5;
    }
};

void test01()
{
    vector<int>v;
    for (int i = 0 ; i < 10; i++)
    {
        v.push_back(i);
    }

    //Find whether there is an array greater than 5 in the container
    //GreaterFiver() is an anonymous function object, which can also be instantiated
    vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFiver());
    if (it == v.end())
    {
        cout << "not found" << endl;
    }
    else
    {
        cout << "A number greater than 5 was found:" << *it << endl;
    }
}

Among them, the algorithm find is used_ If (search interval start position, interval end position and search value), it needs to be received by iterator.

2.3 binary predicate

#include<vector>
#include<algorithm>

class MyCompare
{
public:
    bool operator()(int val1, int val2)
    {
        return val1 > val2;
    }
};

void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(40);
    v.push_back(20);
    v.push_back(30);
    v.push_back(50);

    sort(v.begin(), v.end());
    for(auto i: v)
    {
        cout << i << " ";
    }
    cout << endl;

    //Use the function object to change the algorithm strategy and change the sorting rule from large to small
    sort(v.begin(), v.end(),MyCompare());
    cout << "-----------------" << endl;
    sort(v.begin(), v.end());
    for(auto i: v)
    {
        cout << i << " ";
    }
    cout << endl;
}

Predicates with only two parameters become binary predicates.

3. Built in function object

Meaning of built-in function object:

  • STL has built-in function objects

Classification:

  • Arithmetic imitation function
  • Relational affine function
  • Logical imitation function

Usage:

  • The usage of the objects generated by these imitation functions is exactly the same as that of general functions
  • To use the built-in function object, you need to import the header file #include < functional >

3.1 arithmetic imitation function

Function Description:

  • Realize four operations
  • Among them, negate is a unary operation, and others are binary operations

Imitation function prototype:

  • Template < class T > t plus < T > / / addition functor
  • Template < class T > t minus < T > / / subtraction function
  • Template < class T > t multiples < T > / / multiplication functor
  • Template < class T > t divisions < T > / / division imitation function
  • Template < class T > t module < T > / / take the imitation function
  • Template < class T > t negate < T > / / take the inverse function
negate<int>n;//Take inverse imitation function
cout << n(50) << endl;//-50

plus<int>p;//Add imitation function, write only one template type!
cout << p(10, 20) << endl;//30

3.2 relation imitation function

Function Description:

  • Implement relationship comparison

Imitation function prototype:

  • template<class T>bool equal_ To < T > / / equal to
  • template<class T>bool not_ equal_ To < T > / / not equal to
  • Template < class T > bool greater < T > / / greater than
  • template<class T>bool greater_ Equal < T > / / greater than or equal to
  • Template < class T > bool less < T > / / less than
  • template<class T>bool less_ Equal < T > / / less than or equal to
#include<functional>
#include<vector>
#include<algorithm>

class MyCompare
{
public:
    bool operator()(int v1, int v2)
    {
        return v1 > v2;
    }
};

void test01()
{
    vector<int>v;
    v.push_back(10);
    v.push_back(30);
    v.push_back(40);
    v.push_back(20);
    v.push_back(50);

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    //Descending order
    sort(v.begin(), v.end(), MyCompare());
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    //Using built-in functions
    sort(v.begin(), v.end(), greater<int>());
    sort(v.begin(), v.end(), MyCompare());
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

3.3 logic imitation function

Function Description: (in fact, it is not commonly used)

  • Realize logical operation

Imitation function prototype:

  • template<class T>bool logical_ And < T > / / logic and
  • template<class T>bool logical_ Or < T > / / logical or
  • template<class T>bool logical_ Not < T > / / not logical
#include<functional>
#include<vector>
#include<algorithm>

void test01()
{
    vector<bool>v;
    v.push_back(true);
    v.push_back(false);
    v.push_back(true);
    v.push_back(false);

    for (vector<bool>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    //Using logical negation, the container v is transported into the container v2 and the reverse operation is performed
    vector<bool>v2;
    v2.resize(v.size());//The target container must first open up enough memory space!!
    transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
    //The start iterator of the original container, the end iterator of the original container, the start iterator of the target container, and the imitation function

    for (vector<bool>::iterator it = v2.begin(); it != v2.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

Using the built-in algorithm transform (the start iterator of the original container, the end iterator of the original container, the start iterator of the target container, and the generic function class name < T > (), the handling operation from the original container to the target container is realized, but remember to open up enough memory space for the target container before handling!

Keywords: C++ Container

Added by navid on Wed, 02 Mar 2022 11:58:31 +0200