Reputation: 8688
I am using the gtkmm library on linux to draw a simple menu for my GUI.
In the below code the compiler complained about unable to resolve address
sigc::mem_fun(*this, AppWindow::hide)));
^
appwindow.cpp:15:41: note: could not resolve address from overloaded function
But when I insert the &
it compiles fine
m_menu_app.items().push_back(MenuElem("Quit",
sigc::mem_fun(*this, &AppWindow::hide)));
What difference does it make here? Isn't the hide
function just an address in the first place?
Upvotes: 19
Views: 1423
Reputation: 60999
This is the exact definition of the function-to-pointer conversion, [conv.func]:
An lvalue of function type
T
can be converted to a prvalue of type “pointer toT
.” The result is a pointer to the function.55
55) This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function cannot be obtained.
Thus the decay that we see with normal, non-member functions1 doesn't apply and you need to explicitly take the address.
I.e.
void f();
struct A {
void f();
static void g();
};
auto a = f; // Ok: auto deduced as void(*)()
auto b = A::f; // Error: A::f not an lvalue, auto cannot be deduced
auto c = A::g; // Ok: auto deduced as void(*)()
Upvotes: 15
Reputation: 206717
When a function is a non-static member function of a class, then it is necessary to use the form &ClassName::functionName
when a pointer to the member function is expected in an expression.
When a function is a static member function of a class, both ClassName::functionName
and &ClassName;:functionName
can be used when a pointer to a function is expected in an expression.
When a function is a global, i.e. non-member, function, both functionName
and &functionName
can be used when a pointer to a function is expected in an expression.
Upvotes: 2
Reputation: 490538
For global (non-member) functions, the name of the function evaluates to the address of that function except when passed to the &
operator, so you can (for example) assign to a pointer to a function either with or without the &
equivalently:
int f() {}
int (*pf1)() = f;
int (*pf2)() = &f;
So, in this case there's really no difference between the two.
For member functions1, however, the rules are a bit different. In this case, the &
is required; if you attempt to omit the &
, the code simply won't compile (assuming a properly functioning compiler, anyway).
There's no particular reason this would have to be the case--it's just how Bjarne decided things should be. If he'd decided he wanted the name of a member function to evaluate to a pointer to a member (equivalent to how things work for non-member functions) he could have done that.
1. Other than static member functions, which mostly act like non-member functions.
Upvotes: 6