以下非常简单的例子我写的是为了实现指向成员概念的指针:
struct X
{
void f();
};
void X::*g();//error: 'g' declared as a member pointer to void
int main(){
}
DEMO 正式,标准说:
在声明
T D
中D
的格式为
nested-name-specifier * attribute-specifier-seq_opt cv-qualifier-seqopt D1
和nested-name-specifier表示一个类,以及标识符的类型 在声明
T D1
中是“derived-declarator-type-list T
”,然后是D
标识符的类型是“derived-declarator-type-list” cv-qualifierseq指向类的nested-name-specifier成员的指针 输入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
。
我哪里错了?
答案 0 :(得分:4)
您可以假设g
首先与()
绑定,并为您提供g()
,从而正确开始推导。但仅此一点就意味着g
是函数,它不带参数,不带指针。此时,g
成为指针的所有机会都将永远消失。声明的其余部分将描述函数的返回类型。所以,显然,你的推导是不正确的。 (如果继续推导,您将到达错误消息中指定的类型。)
与运算符类似,声明的后缀部分优先级高于前缀1。这意味着如果您希望g
成为任何类型的指针,则必须先强制g
绑定到*
。这可以通过()
:(*g)
来实现。这将使g
成为常规指针。如果您希望g
拥有指向成员的指针类型,则必须将整个X::*
括在括号中:(X::*g)
。
最后,为了完成声明,我们将它作为一个指向成员的函数,返回void
:void (X::*g)()
。
答案 1 :(得分:2)
推导的最后一步是错误的。 g
是一个"函数,返回指向类X
"的类void
成员的指针。但是,当然不能成为X
类型void
的成员。