看看这个片段:
struct A {
void fn();
};
struct B: A {
};
void f() {
auto x = &B::fn;
}
这里,x
得到了 void (A::*)()
类型,尽管我已经写了 &B::fn
.
如果我将 fn
添加到 B
中,则 x
的类型将为 void (B::*)()
.
因此,&B::fn
的类型会改变 B 是否有 fn
。
这种行为背后的理由是什么?我觉得很奇怪。
为什么这很重要?假设:程序员 X 创建了 A
和 B
,就像我的示例一样。程序员 Y 使用 &B::fn
,并将其类型的类部分用于某些内容(例如模板的参数,等等)。然后程序员 X 意识到,他需要 fn
中的一些额外功能,因此他重写了它。现在,程序员 Y 的代码可以被破坏,因为 &B::fn
的类型已更改。
最佳答案
这是 CWG issue 203 的主题和 EWG issue 89 。最初,其基本原理是允许尽可能多的代码有效:
Notes from 04/00 meeting:
The rationale for the current treatment is to permit the widest possible use to be made of a given address-of-member expression. Since a pointer-to-base-member can be implicitly converted to a pointer-to-derived-member, making the type of the expression a pointer-to-base-member allows the result to initialize or be assigned to either a pointer-to-base-member or a pointer-to-derived-member. Accepting this proposal would allow only the latter use.
后来,当它造成的问题变得更加明显后,再去修复已经来不及了:
Additional note, April, 2015:
EWG has determined that the utility of such a change is outweighed by the fact that it would break code. See EWG issue 89.
关于c++ - 为什么成员函数指针的类型基于实际声明该函数的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47210974/