带括号的成员函数的地址出错

Mah*_*esh 33 c++ function-pointers pointer-to-member

我找到了有趣的东西.错误消息说明了一切.在获取非静态成员函数的地址时不允许使用括号的原因是什么?我在gcc 4.3.4上编译了它.

#include <iostream>

class myfoo{
    public:
     int foo(int number){
         return (number*10);
     }
};

int main (int argc, char * const argv[]) {

    int (myfoo::*fPtr)(int) = NULL;

    fPtr = &(myfoo::foo);  // main.cpp:14

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

错误:main.cpp:14:错误:ISO C++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针.说'&myfoo :: foo'

tem*_*def 27

从错误消息中,您似乎不允许获取带括号的表达式的地址.这表明你重写了

fPtr = &(myfoo::foo);  // main.cpp:14
Run Code Online (Sandbox Code Playgroud)

fPtr = &myfoo::foo;
Run Code Online (Sandbox Code Playgroud)

这是由于规范的一部分(§5.3.1/ 3)所致

仅当使用显式&时,才会形成指向成员的指针,并且其操作数是未括在括号中的限定ID [...]

(我的重点).我不确定为什么这是一个规则(直到现在我才真正知道这一点),但这似乎是编译器所抱怨的.

希望这可以帮助!

  • @templatetypedef我觉得这就是这个问题(我是如何解释的) (4认同)
  • 有趣的。当允许时 `int a = 20; int *ptr = &amp;(a);` ,我不明白非静态成员函数的问题。 (2认同)
  • -1:**问题:**"在获取非静态成员函数的地址时不允许使用括号的原因是什么?"**你的答案:**"你似乎不允许拿一个带括号的表达式的地址"**Me:**">.<"//这也是一个误导性的答案,因为当然`int a; cout <<&(a);`完全有效; 这仅适用于指向成员的指针. (2认同)

Joh*_*itb 16

想象一下这段代码:

struct B { int data; };
struct C { int data; };

struct A : B, C {
  void f() {
    // error: converting "int B::*" to "int*" ?
    int *bData = &B::data;

    // OK: a normal pointer
    int *bData = &(B::data);
  }
};
Run Code Online (Sandbox Code Playgroud)

没有括号的技巧,你将无法直接指向B的数据成员(你需要基类类型的转换和游戏this- 不太好).


来自ARM:

请注意,必须明确使用address-of运算符来获取指向成员的指针; 没有隐式转换......如果有,我们会在成员函数的上下文中产生歧义...例如,

void B::f() {
    int B::* p = &B::i; // OK
    p = B::i; // error: B::i is an int
    p = &i; // error: '&i'means '&this->i' which is an 'int*'

    int *q = &i; // OK
    q = B::i; // error: 'B::i is an int
    q = &B::i; // error: '&B::i' is an 'int B::*'
}
Run Code Online (Sandbox Code Playgroud)

IS只是保留了这个标准之前的概念,并明确提到括号使得你不会得到指向成员的指针.

  • [对于委员会] 解决歧义似乎是一种有趣的方式。 (2认同)