While reading some code, I came across this function. I have lots of trouble understanding the signature of the function. What are the things that I need to know before I can make head or tail of the following code?
I have been using C++ for a while now. I know what templates, function pointers are. However, I cannot make out what T::*
might mean, what the line starting with _Defer
means semantically.
Also, the first line of the function seems quite intimidating. Is there some resource that I can read up before trying to re-assess this code?
template <typename T>
_Defer<void(*(PID<T>, void (T::*)(void)))
(const PID<T>&, void (T::*)(void))>
defer(const PID<T>& pid, void (T::*method)(void))
{
void (*dispatch)(const PID<T>&, void (T::*)(void)) =
&process::template dispatch<T>;
return std::tr1::bind(dispatch, pid, method);
}
Source: https://github.com/3rdparty/libprocess/blob/master/include/process/defer.hpp
In C/C++, the method signature is the method name and the number and type of its parameters, but it is possible to have a last parameter that consists of an array of values: int printf(const char*, ... );
A function signature (or type signature, or method signature) defines input and output of functions or methods. A signature can include: parameters and their types. a return value and type. exceptions that might be thrown or passed back.
Function Signature A function's signature includes the function's name and the number, order and type of its formal parameters. Two overloaded functions must not have the same signature. The return value is not part of a function's signature.
For functions that are specializations of function templates, the signature includes the return type. For functions that are not specializations, the return type is not part of the signature.
This might help clear things up a little:
template<typename T>
using VoidPMemberFn = void(T::*)(); // Pointer to member function of T
// that accepts no arguments and
// returns nothing.
template<typename T>
using DeferResultType = void (*)(const PID<T> &, VoidPMemberFn<T>);
template<typename T>
using DeferSignatureType = DeferResultType<T>(PID<T>, VoidPMemberFn<T>);
template<typename T>
_Defer<DeferSignatureType<T>> defer(const PID<T> &pid, VoidPMemberFn<T> method)
{
// Stuff...
}
EDIT
This might help clarify what the spaghetti in the _Defer
template means, and how it relates to the above:
void(* (PID<T>, void (T::*)(void)) )(const PID<T>&, void (T::*)(void))
^-+^-^ ^-------------------------^ ^-------------+------------------^
| argument list |
| |
+-----------------------------------------------+
return type: void(*)(const PID<T> &, void(T::*)(void))
This creates a "signature", like those used with std::function
(e.g. std::function<int(float)>
).
More examples:
using sig = int(float);
sig gn; // Same as: "int gn(float)", a function declaration
int fn(float x)
{return (int)x;}
int main(int argc, char **argv)
{
// pointer to a function with signature "sig"
sig *pfn = &fn;
return 0;
}
int gn(float x)
{return (int)(x*x);}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With