Document directory
The function object is also called a pseudo function. function objects are originally a class, but since there is basically nothing to do, only one function is encapsulated in it, and the encapsulated function is implemented through the overload operator.
Maybe you are wondering, why is this stuff coming out?
This is actually the case,At the beginning, some simple applications can be completely completed by using a function, just passing a function pointer. However, this is not flexible enough and the scalability is poor, so the entire class is simply available..
Function pointer Defects
Let's take an example ~
If we have a factory to recruit people, then we need to comply with many standards. based on the principle of division of labor and cooperation, the work that judges the conditions is completely completed by another function. (Of course, this is just for the convenience of examples. It is a little far-fetched)
Assume that the isok function (INT userid) is used to determine whether the condition is met.
Bool isok (INT userid)
{
// If the userid is used to search for various information in the database
Int age = getage (userid); // The implementation of this function is omitted, and many other judgment information is ignored.
If (age> 18)
Return true;
Else
Return false;
}
Void printalllaborname (INT userid, string name, bool (* pfun) (INT) // The second parameter is a function pointer.
{
If (pfun (userid) // print the name if the condition is met
Cout <name <Endl;
}
If it is a simple application, just like the above, a function pointer will be transmitted in printalllaborname, but when it suddenly needs other conditions, the function parameters will change. it is inconvenient to change it.
If isok (INT) is changed to isok (INT, string), there must be two changes. One is the isok function itself, and the other is the parameter of printalllaborname.
Then we know that the benefit of object-oriented classes is encapsulation. It is enough to provide external interfaces. to change to the class only, the interface remains unchanged. so we want to encapsulate the isok function into a class..
Function object
Template <class T>
Struct checkcondition // This is a function object, as long as the operator () is overloaded ()
{
Bool operator () (INT userid, t otherinfo) // if there is a lot of information to be transmitted, define a class and then use t to pass it over.
{
// If (check (userid, otherinfo) This function is not implemented here
Return true;
// Else
// Return false;
}
}
Template <class T>
Void printalllaborname (INT userid, string name, t fun) // The second parameter is a function object.
{
If (fun (userid, name) // print the name if the condition is met
Cout <name <Endl;
}
Test code
Printalllaborname (123, "Arwen", checkcondition <string> ());
Confusion when passing functions to function objects
After reading the example, you may have two questions,
One is the benefit of the overload operator,
The other is that function objects are a little weird to use. They don't even see where the class is instantiated.
The advantage of overload () is that its parameters are unrestricted, so you can imitate any function, while other operators (unary operators, binary operators) can only have one or two parameters.
Function Object Instantiation:
First, the form parameter of the function is a class and then called in it. This is easy to understand.
Template <class T>
Void printalllaborname (INT userid, string name, t fun)
Call fun (userid, name)
But I don't understand it here.
Printalllaborname (123, "Arwen", checkcondition <string> ());
The checkcondition <string> () parameter is too strange..
If yesCheckcondition <string> checkcon;
Then printalllaborname (123, "Arwen", checkcon );.
It's okay to instantiate an object and pass it over. In fact, this is all right.
But most of the time we do not use this, but checkcondition <string> (). Why? This is a benefit.
We know that checkcondition <string> checkcon; after instantiating an object in this way, after you call the printalllaborname function, the object still has no scope and is not destructed.
The checkcondition <string> () is to call the constructor. In this way, a temporary object is passed over and the function is destructed once called (this is the benefit of being destructed immediately after the call)
Printalllaborname (123, "Arwen", checkcondition <string> () transmits a parameter in the past, and the action is
Void printalllaborname (INT userid, string name, t fun)
{
// The following two steps are implemented in the background:
Checkcondition <string> TMP;
Fun = TMP;
}