I want to declare type definition for a member function signature. Global function typedefs look like this:
typedef int (function_signature)(int, int);
typedef int (*function_pointer) (int, int);
But I'm not able to the same thing for a member function:
typedef int (foo::memberf_signature)(int, int); // memberf_pointer is not a member of foo
typedef int (foo::*memberf_pointer)(int, int);
It sounds logically to me, because foo::
is the syntax to access a member in the class foo
.
How can I typedef just the signature?
A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared.
A typedef, or a function-type alias, helps to define pointers to executable code within memory. Simply put, a typedef can be used as a pointer that references a function.
You can use pointers to member functions in the same manner as pointers to functions. You can compare pointers to member functions, assign values to them, and use them to call member functions.
The typedef specifier cannot be combined with any other specifier except for type-specifiers. The typedef-names are aliases for existing types, and are not declarations of new types. Typedef cannot be used to change the meaning of an existing type name (including a typedef-name).
For questions regarding the awkward function pointer syntax, I personally use a cheat-sheet: The Function Pointers Tutorial (downloadable here, thanks to Vector for pointing it out).
The signature of a member function, however, is a bit different from the signature of a regular function, as you experienced.
As you probably know, a member function has a hidden parameter, this
, whose type need be specified.
// C++11 and above.
using Member = int (Foo::*)(int, int);
// C++03 and below.
typedef int (Foo::*Member)(int, int);
does let you specify that the first element passed to the function will be a Foo*
(and thus your method really takes 3 arguments, when you think of it, not just 2.
However there is another reason too, for forcing you to specify the type.
A function pointer might refer to a virtual function, in which case things can get quite complicated. Therefore, the very size of the in-memory representation changes depending on the type of function. Indeed, on Visual Studio, a function pointer's size might vary between 1 and 4 times the size of a regular pointer. This depends on whether the function is virtual, notably.
Therefore, the class the function refers to is part of the signature, and there is no work-around.
You can factor out the target class in modern C++ (post 11) by utilizing the 'typedefing' qualities of template aliases. What you need would look like like:
template<typename T>
using memberf_pointer = int (T::*)(int, int);
Yet at the point of declaration, a pointer to member function utilizing this syntax would need to specify the target class:
// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D;
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