Reputation: 6392
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.
Upvotes: 0
Views: 134
Reputation: 153820
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.
Upvotes: 4
Reputation: 7123
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.
Upvotes: 0