Reputation: 458
according to MSDN the typedef syntax is:
typedef type-declaration synonym;
Very easy:
typedef int MY_INT;
But how the heck does the member-function-pointer typedefs comply to this rule?
typedef int (MyClass::*MyTypedef)( int);
100% confusion – the synonym (MyTypedef
) is in the middle?
Can someone please explain what the logical steps are to get from the very easy to understand syntax format of MSDN to the reverse/random/front/last/mixed syntax thing of aboves typedef?
*edit thanks for all the fast answers (and the beautification of my post) :)
Upvotes: 38
Views: 47757
Reputation: 3279
The syntax of using member function pointer has to (assume a
is an instance of class A
):
Below is a toy example. You can play with it.
#include <stdio.h>
#include <stdlib.h>
class A;
typedef int (A::*F)(double);
class A {
public:
int funcDouble(double x) { return (int)(x * 2.0); }
int funcTriple(double x) { return (int)(x * 3.0); }
void set(int a) {
if (a == 2) {
this->f_ = &A::funcDouble;
} else if (a == 3) {
this->f_ = &A::funcTriple;
} else {
this->f_ = NULL;
}
}
public:
F f_;
};
int main(int argc, char *argv[]) {
A a;
a.set(2);
F f = &A::funcDouble;
printf("double of 1 = %d\n", (a.*f)(1));
// Below is equivalent to:
// F f2 = a.f_;
// printf("double of 1 = %d\n", (a.*f2)(1));
printf("double of 1 = %d\n", (a.*(a.f_))(1));
a.set(3);
printf("triple of 1 = %d\n", (a.*(a.f_))(1));
return 0;
}
Upvotes: 6
Reputation: 24259
It's worth noting that, as of C++11, you could write this expression as a more legible using
statement:
using MyTypedef = int (MyClass::*)(int);
Upvotes: 45
Reputation: 14692
I know you've already got your answer, but want to share this - it's handy: http://www.cdecl.org. It's a C/C++ declaration <-> English translator. Just type in
declare x as pointer to member of class A function (int) returning char
and you get char (A::*x)(int )
. Or play around with the declaration and see if you get what you want.
Upvotes: 5
Reputation: 221
It will be easier to understand when you start thinking like this:
Whenever you see a function like this:
TYPE foo(int arg1, int arg2);
You say that the type of foo is TYPE. So, the type of
int get_next_prime();
is int.
You can see that when you pass a function pointer as an argument to a function:
void register_callback(void (*ptr)(int));
In this case, you are passing a function of type void as an argument.
Now, when you see something like that:
typedef int (A::*typedefName)(int);
you are just saying that the variable (A::*typedefName)(int) (this is only one thing, not two, since it's a function pointer declaration) is actually of type int. From then on, the compiler will interpret A::*typedefName as a function of type int, that is, it returns an int value.
Hope it makes it less confusing.
Upvotes: 0
Reputation: 5805
The page you are referring to is probably "typedef Specifier". The simplistic "typedef type-declaration synonim;
" syntax is just one of the many ways to use typedef. There is (probably) no simple and concise way to describe how typedef can be used. That is what the "Typedef Declarations" MSDN page is for.
You will notice on this page something like:
declaration:
declaration-specifiers init-declarator-list opt ;
declaration-specifiers:
storage-class-specifier declaration-specifiers opt
type-specifier declaration-specifiers opt
type-qualifier declaration-specifiers opt
storage-class-specifier:
typedef
More details as to what declaration-specifiers and init-declarator-list can be found here.
This is one rigorous way to understand all possible usages for "typedef".
What this page basically says is that "typedef" can be used before most valid declarations.
Upvotes: 1
Reputation: 361482
the synonym (MyTypedef) is in the middle??
Its not in the middle. Just forget member-function for a while, see how a function pointer is defined:
int (*FuncPtr)(int);
And this is how you would typedef it:
typedef int (*FuncPtr)(int);
Simple! The only difference is, in the typedef FuncPtr
becomes a type, while in the pointer declaration, FuncPtr
is a variable.
Similarly,
int (MyClass::*MyTypedef)( int); //MyTypedef is a variable
And the typedef as:
typedef int (MyClass::*MyTypedef)( int); //MyTypedef is a type!
Upvotes: 49
Reputation: 182649
I once read a nice explanation (but it's from Expect C Programming so I ymmv):
In fact, a typedef has exactly the same format as a variable declaration, only with this extra keyword to tip you off.
Since a typedef looks exactly like a variable declaration, it is read exactly like one. Instead of the declaration saying "this name refers to a variable of the stated type," the typedef keyword doesn't create a variable, but causes the declaration to say "this name is a synonym for the stated type."
So there you have it. Imagine you're declaring a variable, stick typedef
before it and voila, you have a new type. MSDN
explanations are a mixed bag: I've read really god ones and downright bad ones.
Upvotes: 1
Reputation: 52294
The principle for declaration in C++ is that they mimick the use. If you want to use a pointer to member function pmf, you'll write:
(myVar.*pmf)(arg);
so to define a typedef for it, you write:
typedef int (MyClass::*pmf)(int);
adding the return type in head, replacing the variable by the type and arguments by their type.
Upvotes: 4
Reputation: 72489
How do you define a pointer to member function? Like this:
int (A::*variableName)(int);
To make it a typedef, just add a typedef:
typedef int (A::*typedefName)(int);
Upvotes: 11