Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer to function as static member in structure

Tags:

c++

struct X {
   int f(int);
   static int f(long);
};

int (X::*p1)(int) = &X::f; // OK
int (*p2)(int) = &X::f; // error: mismatch
int (*p3)(long) = &X::f; // OK
int (X::*p4)(long) = &X::f; // error: mismatch
int (X::*p5)(int) = &(X::f); // error: wrong syntax for pointer to member
int (*p6)(long) = &(X::f); // OK

I think that p1 and p5 is the same case. Why is p5 wrong?

like image 973
steve1979 Avatar asked Feb 28 '17 20:02

steve1979


2 Answers

Because the standard says so. From the N3936:

5.3.1 Unary operators

  1. A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note ]
like image 62
Edgar Rokjān Avatar answered Sep 18 '22 03:09

Edgar Rokjān


The C++ Standard's definition of the built-in operator & states that only when the parameter to & is a qualified-id, meaning something like Class::Member, does & result in a pointer-to-member. The parentheses make it no longer a qualified-id, so it attempts to parse X::f directly, which is illegal in this context: you're assigning an int (*)(long) to an int (X::*)(int).

The distinction between the two cases resolves an ambiguity. Let's say that you have:

struct X {
    int m;
};
struct Y {
    int m;
};
struct Z : X, Y {
    void F();
};

void Z::F() {
    int X::*p1 = &X::m;
    int *p2 = &(X::m);
}

Here, &X::m is a pointer-to-member, whereas &(X::m) is an ordinary pointer to int, using the X:: qualification to resolve the ambiguity between X's m and Y's m.

like image 30
Myria Avatar answered Sep 20 '22 03:09

Myria