&foo :: function和foo :: function有什么区别?

Mar*_*ark 19 c++ function-pointers

我在linux上使用gtkmm库为我的GUI绘制一个简单的菜单.

在下面的代码中,编译器抱怨无法解析地址

        sigc::mem_fun(*this, AppWindow::hide)));
                                         ^
appwindow.cpp:15:41: note:   could not resolve address from overloaded function
Run Code Online (Sandbox Code Playgroud)

但是当我插入&它时编译很好

m_menu_app.items().push_back(MenuElem("Quit",
    sigc::mem_fun(*this, &AppWindow::hide)));
Run Code Online (Sandbox Code Playgroud)

它在这方面有什么不同?这个hide功能首先不是一个地址吗?

Col*_*mbo 15

这是函数到指针转换的确切定义,[conv.func]:

函数类型的左值T可以转换为"指向T" 的类型的prvalue .结果是指向函数的指针.55


55) 此转换从不适用于非静态成员函数,因为无法获取引用非静态成员函数的左值.

因此,我们在普通非成员函数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(*)()
Run Code Online (Sandbox Code Playgroud)


1或静态成员函数.

  • 唯一的答案解释了它背后的原因. (3认同)

Jer*_*fin 6

对于全局(非成员)函数,函数的名称求值为该函数的地址,除非传递给&运算符,因此您可以(例如)使用或不使用&等效的方式分配给函数的指针:

int f() {}

int (*pf1)() = f;
int (*pf2)() = &f;
Run Code Online (Sandbox Code Playgroud)

所以,在这种情况下,两者之间确实没有区别.

但是,对于成员函数1,规则略有不同.在这种情况下,&是必需的; 如果你试图省略&,代码根本就不会编译(假设一个正常运行的编译器,无论如何).

没有特别的理由可以这样 - 这就是Bjarne决定应该如何做的事情.如果他决定他想要一个成员函数的名称来评估指向一个成员的指针(相当于非成员函数的工作方式),他就可以做到这一点.


1.静态成员函数以外的函数,其作用大多类似于非成员函数.