指向不完整类型成员函数的指针

pointer to member function of incomplete type

我不明白为什么为 class 添加前向声明会更改其指向成员类型的指针的大小

#include <iostream>
using namespace std;

int main()
{
    //struct CL;
    //cout<<sizeof(int (CL::*)())<<endl; 
    struct CL{};
    cout<<sizeof(int (CL::*)())<<endl;
}

输出 VS2013:
4

但是如果我在 main() 中取消注释前两行,那么输出就会不同:
16
16

因此,只需在 struct CL 的定义之前添加前向声明即可增加指向 CL 成员的指针的大小。为什么?我知道成员函数指针的大小取决于类型的结构(例如虚函数和基 classes 可能会增加它),但为什么 sizeof 运算符可以应用于指向不完整类型成员的指针?或者它不能?我没有在标准中找到它

MSVC 编译器使用不同大小的成员函数指针作为优化。这种优化违反了标准。感谢 Igor Tandetnik mentioning reinterpret_cast in a MSDN form post、[expr.reinterpret.cast]p10

A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types. The null member pointer value is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases:

  • converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original type yields the original pointer to member value.

所以有往返保证,这有效地强制了符合要求的实现对所有指向成员函数类型的指针使用相同的大小。


如果 /vmb switch is set. For the case of single inheritance, the optimised pointer to member function requires only a void*-sized storage, see The Old New Thing: Pointers to member functions are very strange animals.

执行 MSVC 优化

如果您只前向声明类型 CL,然后形成一个指向成员函数的指针,则优化有望停用(不幸的是,我找不到任何相关文档)。否则,您可能会在 CL.

的定义前后得到不一致的大小

顺便说一下,如果你在 VS2010 中前向声明它们 而不指定底层类型 并且稍后为定义显式定义底层类型,你可能会得到不一致的大小枚举的。这仅适用于激活的语言扩展。