The rule that typedef declarations have the same syntax as ordinary variable and function declarations can be used to read and write more complex declarations.

void (*f)(int);         // f has type "pointer to function of int returning void"
typedef void (*f)(int); // f is an alias for "pointer to function of int returning void"

This is especially useful for constructs with confusing syntax, such as pointers to non-static members.

void (Foo::*pmf)(int);         // pmf has type "pointer to member function of Foo taking int
                               // and returning void"
typedef void (Foo::*pmf)(int); // pmf is an alias for "pointer to member function of Foo
                               // taking int and returning void"

It is hard to remember the syntax of the following function declarations, even for experienced programmers:

void (Foo::*Foo::f(const char*))(int);
int (&g())[100];

typedef can be used to make them easier to read and write:

typedef void (Foo::pmf)(int);  // pmf is a pointer to member function type
pmf Foo::f(const char*);       // f is a member function of Foo

typedef int (&ra)[100];        // ra means "reference to array of 100 ints"
ra g();                        // g returns reference to array of 100 ints