Mark
Mark

Reputation: 8688

What is the difference between &foo::function and foo::function?

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

Answers (3)

Columbo
Columbo

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 to T.” 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(*)()


1 Or static member functions.

Upvotes: 15

R Sahu
R Sahu

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

Jerry Coffin
Jerry Coffin

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

Related Questions