c++ - 为什么成员函数指针的类型基于实际声明该函数的类?

标签 c++

看看这个片段:

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 创建了 AB,就像我的示例一样。程序员 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/

相关文章:

c++ - std::shuffle 的使用和效用?

c++ - CCSprite 在 COCOS2dx 中不作为物理体?

c++ - 组件测试的测试框架

c++ - 为什么 Prefix Increment Overload 返回的是 Type 而不是 Type?

c++ - 从 C++ 自动登录网站

c++ - 是否存在 fseek/ftell 给出错误文件大小的情况?

c++ - 带有 constexpr 函数失败的模板实例化

c++ - 可以将参数类型转换为 std::min() 吗?

c++ - 将文件中的数据存储到C++中的二维数组中

c++ - 使用带有嵌套结构的模板化 lambda 时的类型推导 + 分析可能未使用的程序集输出