为什么它是指向 void 声明符的指针而不是指向成员函数的指针

Why is it a pointer to void declarator instead of a pointer to member function?

本文关键字:指针 函数 成员 声明 void 为什么      更新时间:2023-10-16

下面这个非常简单的例子是为了实现指向成员概念的指针:

struct X
{
    void f();
};
void X::*g();//error: 'g' declared as a member pointer to void
int main(){
}

演示正式地,该标准说:

在声明T D中,D具有以下形式

nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seqopt D1

嵌套名称说明符表示类,以及标识符的类型 在声明中T D1是" derived-declarator-type-list T ",则 D标识符的类型是"派生声明器类型列表" cv-qualifierseq 指向类成员的指针 嵌套名称说明符 键入T"。

特别是在我的情况下,我们有:

D1 g()

T void

nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seqopt X::*

derived-declarator-type-list T funtion returned void

所以声明 T D 必须引入一个function pointer to member of class X returnned void

我错在哪里?

你通过假设g首先与()绑定来正确地开始你的推导,给你g()。但仅此一项就已经意味着g是一个不带参数的函数,而不是指针。在这一点上,g成为指针的所有机会都永远消失了。声明的其余部分将描述函数的返回类型。所以,很明显,你的推导是不正确的。(如果继续派生,将到达错误消息中指定的类型(。

与运算符类似,声明的后缀部分比前缀部分具有更高的优先级。这意味着,如果您希望g成为任何类型的指针,则必须首先强制g绑定到*。这是通过使用()(*g) 来实现的。这将使g成为指向某物的常规指针。如果希望g具有指向成员的指针类型,则必须将整个X::*括在括号中:(X::*g)

最后,为了完成声明,我们使其成为一个指向成员的指针函数,返回voidvoid (X::*g)()

推导的最后一步是错误的。 g是一个"返回指向类型 voidX 成员的指针的函数"。但是当然不能有voidX的成员。