For non-member functions, a type such as typedef void(Function)()
has several uses, but for member functions the only application is to declare a variable which holds a function pointer. Hence, other than a stylistic preference, there's no strict need to allow this syntax and it has been omitted from the standard.
Background
The ::
is a scope resolution operator, and the syntax X::Y
is reserved for static
member access if X
is a class type. So X::*Z
was another syntax invented to define pointer-to-member.
Forget member-function for a while, just think about member-data, and see this code:
struct X
{
int a;
};
int X::*pa = &X::a; //pointer-to-member
X x = {100}; //a = 100
cout << (x.*pa) << endl;
It defines a pointer-to-member-data, and the cout
uses it to print the value of a
of object x
, and it prints:
100
Demo : http://www.ideone.com/De2H1
Now think, if X::pa
(as opposed to X::*pa
) were allowed to do that, then you've written the above as:
int X::pa = X::a; //not &X::a
Seeing this syntax, how would you tell if X::a
is a static
member or non-static member? That is one reason why the Standard came up with pointer-to-member syntax, and uniformly applies it to non-static member-data as well as non-static member-function.
In fact, you cannot write X::a
, you've to write &X::a
. The syntax X::a
would result in compilation error (see this).
Now extend this argument of member-data to member-function. Suppose you've a typedef defined as:
typedef void fun();
then what do you think the following code does?
struct X
{
fun a;
};
Well, it defines member a
of type fun
(which is function taking no argument, and returning void), and is equivalent to this:
struct X
{
void a();
};
Surprised? Read on.
struct X
{
fun a; //equivalent to this: void a();
};
void X::a() //yes, you can do this!
{
cout << "haha" << endl;
}
We can use exactly the same syntax to refer to a
which is now a member-function:
X x;
x.a(); //normal function call
void (X::*pa)() = &X::a; //pointer-to-member
(x.*pa)(); //using pointer-to-member
The similarity is the synatax on the right hand side : &X::a
. Whether a
refers to a member-function or member-data, the syntax is same.
Demo : http://www.ideone.com/Y80Mf
Conclusion:
As we know that we cannot write X::a
on the RHS, no matter if a
is a member-data or member-function. The only syntax which is allowed is &X::f
which makes it necessary that the target type (on LHS) must be pointer as well, which in turn makes the syntax void (X::*pa)()
absolutely necessary and fundamental, as it fits in with other syntax in the language.