Ced*_* H. 16 c++ member-function-pointers member-pointers
如果C++ FAQ Lite中的以下内容为真:"函数名称衰减到指向函数的指针"(因为数组名称衰减为指向其第一个元素的指针); 为什么我们必须加入&符号?
typedef int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = &Fred::f;
Run Code Online (Sandbox Code Playgroud)
而不只是:
typedef int (Fred::*FredMemFn)(char x, float y);
FredMemFn p = Fred::f;
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,Fred :: f是一个函数,可以衰减到指向该函数的指针.
我希望这个问题不是那么愚蠢.
Arm*_*yan 17
原始答案:
因为成员函数不是函数而成员函数指针不是函数指针.因此,腐烂规则不适用.
此外,C++中有函数类型,但不是成员函数类型.因此,您可以在需要指向函数的位置使用函数,但是您不能使用成员函数,因为没有这样的东西,只有指向成员函数的指针.你的例子中的f是一个函数.另一方面,Fred :: f是......好吧,没什么.
此外,我认为"功能的名称可能会腐烂......".不,名称不能做任何事情,函数类型的左值可以隐式转换为指向函数的指针,就重载解析而言,这是一个身份转换
编辑以澄清我的答案:
C++中的每个表达式都有一个类型和值.偶尔可以将一种类型的值转换为另一种类型的值.对这些转换进行排序,以使一次转换更好,另一次转换主要用于函数重载解析.
其中一种转换类型称为左值到右值转换.当左值出现在需要右值的上下文中时,将发生此转换.通常这种转换什么都不做,例如:
int i = 4, j = 5;
i = j;
Run Code Online (Sandbox Code Playgroud)
在第二行j上是一个左值,但这里需要一个右值,因此j被转换为右值.但这不是一个可观察到的转换,是吗?但是有些情况下可以观察到左值到右值的转换.也就是说,n T数组的左值可以转换为类型的右值,T*其值是数组的第一个元素的地址,以及 类型为"带签名S的函数"的左值,类型为"指向函数的指针"的右值签名S",其值是函数的地址
这意味着当我们将函数赋值给函数指针时,函数lvalue会隐式转换为它的地址.
void f() {}
void (*p) () = f; //f is converted to rvalue
Run Code Online (Sandbox Code Playgroud)
f是一个表达式并且有一个类型.f的类型是void()
C++中没有这样的类型作为一个member-function
指向成员函数的指针,而不是成员函数本身.我当然在谈论非静态功能.静态函数的工作方式与普通函数相同,也就是说,您不必编写&X::f,而是可以编写X::f
为什么?因为X :: f具有类型函数并且发生上述转换.但是,如果f是非静态的,那么X :: f的类型是什么?哦,是的,它没有类型,因此不是表达式,因此没有值,因此该值不能转换为任何值.
引用标准:5.3.1子句3只有当使用显式&时,才会形成指向成员的指针,并且其操作数是未括在括号中的qualified-id.[注意:也就是说,表达式&(qualified-id),其中qualified-id括在括号中,不形成"指向成员的指针"类型的表达式.也不是qualified-id,因为没有隐式转换从非静态成员函数的限定id到类型"指向成员函数的指针",因为从函数类型的左值到类型"指向函数的指针"(4.3).即使在unqualified-id类的范围内,也不是&nonqualified-id指向成员的指针.]
希望这更清楚......