&foo::function 和 foo::function 有什么区别?
What is the difference between &foo::function and foo::function?
我正在 linux 上使用 gtkmm 库为我的 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
函数不就是一个地址吗?
这是函数到指针转换的确切定义,[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.
因此,我们在普通非成员函数中看到的衰减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,但是,规则有点不同。在这种情况下, &
是必需的;如果您试图省略 &
,则代码根本无法编译(假设编译器正常运行)。
没有什么特别的理由一定会是这种情况——这就是 Bjarne 决定事情应该如此的方式。如果他决定他想要一个成员函数的名称来评估一个指向成员的指针(相当于非成员函数的工作方式),他就可以做到这一点。
1.除了静态成员函数,它们大多像非成员函数一样。
当函数是 class 的非静态成员函数时,当表达式中需要指向成员函数的指针时,有必要使用 &ClassName::functionName
形式。
当函数是 class 的静态成员函数时,当表达式中需要指向函数的指针时,ClassName::functionName
和 &ClassName;:functionName
都可以使用。
当函数是全局函数,即非成员函数时,当表达式中需要指向函数的指针时,functionName
和 &functionName
都可以使用。
我正在 linux 上使用 gtkmm 库为我的 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
函数不就是一个地址吗?
这是函数到指针转换的确切定义,[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.
因此,我们在普通非成员函数中看到的衰减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,但是,规则有点不同。在这种情况下, &
是必需的;如果您试图省略 &
,则代码根本无法编译(假设编译器正常运行)。
没有什么特别的理由一定会是这种情况——这就是 Bjarne 决定事情应该如此的方式。如果他决定他想要一个成员函数的名称来评估一个指向成员的指针(相当于非成员函数的工作方式),他就可以做到这一点。
1.除了静态成员函数,它们大多像非成员函数一样。
当函数是 class 的非静态成员函数时,当表达式中需要指向成员函数的指针时,有必要使用 &ClassName::functionName
形式。
当函数是 class 的静态成员函数时,当表达式中需要指向函数的指针时,ClassName::functionName
和 &ClassName;:functionName
都可以使用。
当函数是全局函数,即非成员函数时,当表达式中需要指向函数的指针时,functionName
和 &functionName
都可以使用。