Define function objects
Time: 2001/02/07 15:22 Author: vckbase VC knowledge base
Although the function pointer is widely used to implement function callbacks, C provides an important way to implement callback functions, that is, function objects. Function objects (also known as "operator") are heavy-duty "()" ordinary objects. So from grammar, the function object is similar to the normal function behavior.
With a function object instead of a function pointer, there are several advantages, first, because the object can be modified inside and without changing the external interface, the design is more flexible and flexible. Function objects also have data members with previous call results. When using a normal function, you need to store the result of previously calls in full or local static variables, but the full or local static variables have some defects we don't want to see.
Second, in the function object, the compiler can achieve internal calls, thereby further enhancing performance. This is almost impossible in the function pointer.
The following example shows how to define and use a function object. First, declare an ordinary class and overload "()" operator:
Class Negate
{
PUBLIC:
INT Operator () (int N) {return -n;}
}
In the overloaded operation statement, remember that the first circular projection is always empty because it represents the operator name of the overload; the second circular projection is a list of parameters. Generally, when the overload operator, the number of parameters is fixed, and the overload "()" operator is different, and it can have any multiple parameters.
Because the operation in Negate is a dollar (only one operand), the overloaded "()" operator has only one parameter. The return type is the same as the parameter type - INT is INT in this example. The function returns an integer opposite to the parameter symbol.
Use functions
We now define a function called callback () to test function objects. Callback () has two parameters: a reference to the int one is a reference to the class NEGATE. Callback () uses a function object NEG as a normal function name:
#include
Using std :: cout;
Void Callback (int N, Negate & NEG)
{
INT VAL = NEG (N); // Call the operator "()"
Cout << Val;
}
In the unnecessary code, note that NEG is an object, not a function. Compiler will state
INT VAL = NEG (N);
transform into
INT VAL = Neg.operator () (N);
Typically, the function object does not define the constructor and the destructor. Therefore, no problem will occur during creating and destroying. As mentioned earlier, the compiler can be loaded in the operator code, so it avoids runtime issues related to the function call.
In order to complete the above example, we use the main function main () to pass the parameters of callback ():
int main ()
{
Callback (5, Negate ()); // Output -5
}
This example passes an integer 5 and a temporary NEGATE object to Callback (), and then the program outputs -5.
Template functions
As can be seen from the above example, its data type is limited to int, and versatility is one of the advantages of function objects, how to create a versatile function object? The method is to use the template, that is, the operator "()" is defined as class member template so that the function object is suitable for any data type: such as Double, _int64 or char:
Class genericnegate
{
PUBLIC:
Template
T operator () (t t) const {return -t;}
}
int main ()
{
GenericNegate Negate; Cout << Negate (5.3333); // Double
COUT << Negate (10000000000i64); // __INT64
}
If the above flexibility is achieved with a normal callback function is quite difficult.
Standard library function object
The C standard library defines several useful functions, which can be placed in the STL algorithm. For example, the sort () algorithm is determined as its third parameter as its third parameter. The judgment object is a template-based function object that returns the Boolean result. You can deliver Greater <> or LESS <> to Sort () to force the ordering or descending order of sorting:
#include
// for greater <> and less <>
#include
// for sort ()
#include
Using namespace std;
int main ()
{
Vector
VI;
// .. filling vector
sort (vi.begin (), vi.end (), Greater
()); // descending
Sort (vi.begin (), vi.end (), less
()); // ascending
}