成员函数指针能否直接用于reinterpret_cast?相关标准或cppreference依据查询
成员函数指针能否直接用于reinterpret_cast?相关标准或cppreference依据查询
这是个很有意思的细节问题,我来帮你梳理清楚背后的规则和依据~
先看你给出的代码示例,直观呈现了这个差异:
struct X { void func() {} }; int main() { auto p1 = &X::func; // 成员函数指针类型 auto p2 = &p1; // 指向成员函数指针的指针(普通对象指针类型) // reinterpret_cast<int *>(p1); // 编译错误:不允许直接转换成员函数指针 reinterpret_cast<int *>(p2); // 合法:指向成员函数指针的指针属于普通对象指针 }
核心原因:两类指针的类型本质不同
- 成员函数指针是特殊类型:C++里的成员函数指针(pointer to member function)不属于普通的「对象指针」或「自由函数指针」范畴,它的内存结构和类型规则是独立的。标准对这类指针的转换有严格限制,
reinterpret_cast不支持直接将它转换为整数指针或其他普通指针类型。 - 指向成员函数指针的指针是普通对象指针:而
p2指向的是p1这个存储在内存中的变量,它本质就是一个普通的对象指针——和指向int、std::string变量的指针没有本质区别,因此符合reinterpret_cast允许的转换规则。
标准与cppreference的依据
标准层面
在C标准的**[expr.reinterpret.cast]**章节(比如C20的7.6.10节)里明确规定:
reinterpret_cast允许在对象指针类型和整数类型之间互相转换,也支持不同对象指针类型之间的转换;但成员函数指针既不属于对象指针类型,也不属于自由函数指针类型,因此直接将其转换为int*这类类型是被禁止的。
而指向成员函数指针的指针属于对象指针类型(因为它指向的是一个存储成员函数指针的实体),所以可以进行这类转换。
cppreference文档
cppreference在reinterpret_cast的说明中也明确指出:
成员函数指针无法直接转换为普通指针类型(如
void*或整数类型),反之亦然。但指向成员函数指针的指针是普通的对象指针,不受此限制,可以参与reinterpret_cast的相关转换操作。
备注:内容来源于stack exchange,提问作者Benny Hu
相关产品推荐
相关产品推荐

