muxmux
muxmux

Reputation: 458

typedef syntax with member function pointers

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

Answers (9)

zhanxw
zhanxw

Reputation: 3279

The syntax of using member function pointer has to (assume a is an instance of class A):

  • in declaration, use "A::" as prefix
  • when use it, use "a." as prefix

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

kfsone
kfsone

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

davka
davka

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

Felipe Sodre Silva
Felipe Sodre Silva

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

Nick
Nick

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

Sarfaraz Nawaz
Sarfaraz Nawaz

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

cnicutar
cnicutar

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

AProgrammer
AProgrammer

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

Yakov Galka
Yakov Galka

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

Related Questions