Pointer to member function - syntax

171 views Asked by At
void foo();
class Foomatic() {
    void bar();
    void baz()
    {
        std::thread a(foo); // this compiles
        std::thread b(Foomatic::bar, this); // this doesn't 
        std::thread c(&Foomatic::bar, this); // and this compiles
        // ...
    }
};

I know that the correct syntax for the pointer to member function is &Foomatic::bar.

But why exactly is Foomatic::bar incorrect? What does that one return? And why exactly is the &Foomatic::bar the correct one? It seems counter-intuitive to me.

This is not a duplicate. The question you linked to answers what the correct syntax is, not explaining the reasons why.

I'm asking why C++ is so inconsistent here, I already know what the syntax is.

2

There are 2 answers

0
Dietmar Kühl On BEST ANSWER

C++ inherited the conversion from functions to function pointers from C: in C you could just assigne a function name to a function pointer without the need to take the address. This "decay" of function names to function pointers seems somewhat ill-advised and did cause some confusion in C.

When pointers to members where introduced there was no need to be backward compatible with C: C doesn't have pointers to members. Thus, there was the option to not have an implicit conversion from a member name to a pointer to member. Since a facility can be added later if it feels necessary but hardly removed the choice was made to not have an implicit conversion from a member name to pointer to member.

Since there is a reasonably consistent interface to get pointers to functions, pointers to members, and pointers to objects there doesn't seem to be a need to have implicit conversions from member names to pointer to member pretty much as there is no implicit conversion from an object name to a pointer to an object.

Semantically, something like T::member is a reference to a member rather than pointer to a member. However, I don't think it is possible to formulate this type with the current specification. Possibly, a future standard defines someting for this syntax.

0
Paul J. Lucas On

If &Foomatic::Bar is a pointer-to-member function (because you're taking the address of the function using the address-of operator &), then Foomatic::Bar is a member function, not a pointer-to-member function.

This is exactly the same with non-member functions: if &foo is a pointer to (non-member) function, then foo is a function.

Neither C++ nor C have functions as first-class objects, e.g., you can't have a variable whose type/value is a function --- only a pointer thereto.

As a syntactic sugar special case for non-member functions, you can call said function without having to deference it first explicitly, e.g, foo(42) is a short-hand for (*foo)(42) if foo is a pointer to (non-member) function.