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!