指向不完全类型的成员函数的指针 [英] pointer to member function of incomplete type

查看:182
本文介绍了指向不完全类型的成员函数的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I don't understand why adding a forward declaration for a class changes a size of its pointer to member type

#include <iostream>
using namespace std;

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

输出VS2013:

4

output VS2013:
4

但是如果我取消注释main()中的前两行,则输出不同:

16

16

But if I uncomment the first two lines in main(), then the output is different:
16
16

因此,在struct CL的定义之前只需简单的添加一个forward声明,就会增加指向CL成员的指针的大小。为什么?我知道成员函数指针的大小取决于类型的结构(例如,虚函数和基类可能增加它),但为什么可以将sizeof操作符应用于指向不完整类型的成员的指针?还是不能?我没有找到它在标准

So, only a simple adding a forward declaration before a definition of struct CL increases a size of a pointer to member of CL. Why? I know that a size of member function pointer depends by structure of a type (e.g. virtual functions and base classes may increase it), but why can the sizeof operator be applied to a pointer to member of an incomplete type? Or it can't? I have not found it in the Standard

推荐答案

MSVC编译器使用不同的大小作为成员函数的指针作为优化。此优化违反了标准。感谢 Igor Tandetnik reinterpret_cast 中提及< a href =https://social.msdn.microsoft.com/Forums/vstudio/en-US/a9cfa5c4-d90b-4c33-89b1-9366e5fbae74/strange-error-while-casting-pointers-to-member-functions? forum = vclanguage>一个MSDN表单post ,[expr.reinterpret.cast] p10

The MSVC compiler uses different sizes for pointers to member functions as an optimization. This optimization violates the Standard. Kudos to Igor Tandetnik mentioning reinterpret_cast in a MSDN form post, [expr.reinterpret.cast]p10


T1 类型的 X 的成员可以是
显式地转换为不同类型的prvalue指向
类型 T2 Y 成员if T1 T2 都是函数类型
或两个对象类型。空成员指针值转换为
目标类型的空成员指针值。
此转换的结果未指定,但以下情况除外:

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:


  • 将类型指针的prvalue转换为成员函数指向成员函数类型的不同指针,并返回其原始
    类型,产生指向成员值的原始指针。

因此,有一个往返保证,这有效地迫使符合的实现使用相同的大小为所有指向成员函数类型的指针。

So there's a roundtrip guarantee, this effectively forces conforming implementations to use the same size for all pointer to member function types.

如果 / vmb 开关。对于单继承的情况,成员函数的优化指针只需要一个 void * 大小的存储,参见旧的新事物:成员函数的指针是非常奇怪的动物

The MSVC optimization is performed if the /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.

如果你只转发声明类型 CL ,然后形成指针成员函数,希望优化被取消激活(我找不到任何文档,不幸的是)。否则,您可能会在 CL 的定义之前和之后得到不一致的大小。

If you only forward-declare the type CL and then form a pointer-to-member function, the optimization hopefully is deactivated (I could not find any documentation on that, unfortunately). Otherwise, you might get inconsistent sizes before and after the definition of CL.

顺便说一下,如果您在不指定底层类型的情况下向前声明它们,并且稍后显式定义枚举定义的基础类型,则VS2010中枚举的大小不一致。这只适用于已启用的语言扩展。

By the way, you can get inconsistent sizes for enumerations in VS2010, if you forward-declare them without specifying an underlying type and later explicitly define the underlying type for the definition of the enum. This works only with language extensions activated.

这篇关于指向不完全类型的成员函数的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆