typedef int (*function)(int,double);
could anyone explain how typedef'ing a function works? and why someone would use this?
Printable View
typedef int (*function)(int,double);
could anyone explain how typedef'ing a function works? and why someone would use this?
First note that you can only typedef a function pointer, not the function itself.
I, personally, really prefer typedefing function pointers because I hate their declaration syntax and want to use it as rarely as possible. :D
Function pointers were, for instance, used in classical C to implement some kind of polymorphism, which nowadays, in C++, is done using virtual functions. (And, BTW, these virtual functions are usually implemented internally in terms of function pointers by the compiler.) It is a way of specifying an object's behaviour at runtime.
Look at this small example:
The example is drastically simplified and as such not of much practical use. But I once wrote a math expression parser that built a tree of similar structures, and the entire expression could later be evaluated by simply kicking off evaluation of the root node. (But that involved a lot of void pointers and evil casting, and it was definitely anti-C++ style. :D)Code:#include <iostream>
struct math_operation; // Forward declaration
typedef int (*math_operator)(math_operation *); // The function pointer typedef
struct math_operation {
math_operator op; // Operator function
int operand_l, operand_r; // Two operands
};
int op_add(math_operation *operation) // Add operator
{
return operation->operand_l + operation->operand_r;
}
int op_subtract(math_operation *operation) // Subtract operator
{
return operation->operand_l - operation->operand_r;
}
int main()
{
math_operation add, sub;
// Set up addition
add.op = op_add; // Take address of operator function
add.operand_l = 2;
add.operand_r = 3;
// Set up subtraction
sub.op = op_subtract;
sub.operand_l = 4;
sub.operand_r = 5;
// Evaluate the two operation structs
std::cout << "Result of the addition: " << add.op(&add) << std::endl;
std::cout << "Result of the subtraction: " << sub.op(&sub) << std::endl;
return 0;
}
Note that the operator function in the example gets passed a pointer to the struct it belongs to in order to find its operands. This pointer is passed implicitly in C++ and is available under the keyword this inside a member function. (And it is dereferenced implicitly by simply using the names of class members.)
Another very common use of function pointers, at least under Windows, is accessing functions inside a DLL if the DLL is linked in at runtime (as opposed to load-time linking). The GetProcAddress() API function used to obtain a function's address returns a function pointer, and its return type FARPROC in fact is a typedef for that.
HTH
Very good post by Eri523. I'd like to expand just a bit on this one statement.
One common use of the typedef / LoadLibrary() / GetProcAddress() method is to support the latest operating system features in your software while still being compatible with older systems.
For example, if you hard-code an API function that is only available in Windows Vista and 7, then your program will not load on XP and earlier systems. If you use the typedef method then you can support the newer features when your program is running on Vista/7 and provide a less modern alternative for older systems.
You can also have references to functions too.
This has the disadvantage over pointers in that the reference cannot be reseated like a pointer can, nor can it be NULL, but if you never need pass in a NULL or need to reseat the pointer then use a reference instead.Code:typedef int (&Function)(int, double);
If you want to be able to support functors in addition to functions, then you have two options. If you don't need to store the function/functor persistently anywhere, then you just use a template to deduce its type. If you do need to store it, then you can use a std::function<int (int, double)> (or a boost::function on older compilers) which is capable of storing any function pointer or functor with a given signature.