В чем разница между &foo::function и foo::function?
Я использую библиотеку gtkmm в linux, чтобы нарисовать простое меню для моего GUI.
В приведенном ниже коде компилятор жаловался на невозможность разрешить адрес
        sigc::mem_fun(*this, AppWindow::hide)));
                                         ^
appwindow.cpp:15:41: note:   could not resolve address from overloaded function
Но когда я вставляю &, он компилируется отлично 
m_menu_app.items().push_back(MenuElem("Quit",
    sigc::mem_fun(*this, &AppWindow::hide)));
Какая здесь разница? Разве функция hide не является просто адресом в первую очередь?
3 ответа:
Это точное определение преобразования функции в указатель, [conv.func]:
Значение lvalue типа функции
Tможет быть преобразовано в prvalue типа "указатель наT."Результатом является указатель на функцию.55
55)это преобразование никогда не применяется к нестатическим функциям-членам, поскольку значение lvalue, которое ссылается на нестатическую функцию-член невозможно получить .
Таким образом, распад, который мы смотрите с обычными функциями, не являющимися членами1 не применяется, и вам нужно явно взять адрес.
То есть
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 или статические функции-члены.
Для глобальных (не являющихся членами) функций имя функции вычисляется по адресу этой функции, за исключением тех случаев, когда оно передается оператору
&, поэтому вы можете (например) назначить указатель на функцию либо с&, либо без него эквивалентно:Таким образом, в данном случае нет никакой разницы между ними.int f() {} int (*pf1)() = f; int (*pf2)() = &f;Для функций членов 1, однако правила немного отличаются. В этом случае требуется
Нет никакой особой причины, по которой это должно было бы быть так-просто так решил Бьярне. Если бы он решил, что ему нужно имя функции-члена, чтобы вычислить указатель на член (эквивалентно тому, как все работает для функций, не являющихся членами), он мог бы это сделать.&; Если вы попытаетесь опустить&, код просто не будет компилироваться (предполагая, что правильно функционирующий компилятор, в любом случае).
1. Кроме статических функций-членов, которые в основном действуют как не-члены функции.
Если функция является нестатической функцией-членом класса, то необходимо использовать форму
&ClassName::functionName, когда в выражении ожидается указатель на функцию-член.Когда функция является статической функцией-членом класса, можно использовать как
ClassName::functionName, так и&ClassName;:functionName, когда в выражении ожидается указатель на функцию.Если функция является глобальной, то есть не является членом, то можно использовать как
functionName, так и&functionName, когда указатель на функцию ожидается в выражение.