10

The following code:

struct X
{
    void f() {}

    void g()
    {
        auto h = &f;
    }
};

results in:

error: ISO C++ forbids taking the address of an unqualified
or parenthesized non-static member function to form a pointer
to member function.  Say ‘&X::f’

My question is, why is this not allowed and forbidden by the standard? It would be more convenient as a user to refer to it unqualified, so I assume there is some other rationale (safety? an ambiguity? ease of compiler implementation?) for the requirement?

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319

2 Answers2

7

pointer-to-member is rare enough to allow special treatment and not necessarily the most economic one. It was decided that the only accepted form is the one quoted in the error message. That form does not clash with anything else under any circumstances. And prevents ambiguity of more lax forms were allowed.

Practice shows little awareness of PTMFs, and the fact they fundamentally differ from functions. f or &f is likely a request for a normal function. One that can't be served for a nonstatic member. And those who actually mean PTMF say so adding the &X:: part.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37
  • 1
    I don't mean to be rude in asking the following - but is your answer speculative? or do you have direct knowledge that this was the rationale behind the decision? – Andrew Tomazos Jun 02 '13 at 03:16
  • 1
    not completely speculative. I asked this same question 10+ years ago on comp.std.c++ facing a similar issue the first time. (IIRC porting code from MSVC5 to gcc that was more picky). It's my best recollection of answers I got from people, mostly actually working in or by WG21. You can try to dig out one of those threads. – Balog Pal Jun 02 '13 at 03:38
0

You're taking the address of a member function, not a function, and that means you will have to call it differently, too.

struct X
{
    void f() {}

    void g()
    {
        auto h = &X::f;
        h();
    }
};

Produces:

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘h (...)’, e.g. ‘(... ->* h) (...)’
kfsone
  • 23,617
  • 2
  • 42
  • 74