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

发布于 2024-11-30 17:39:02 字数 481 浏览 4 评论 0原文

我发现了一些有趣的事情。错误消息说明了一切。获取非静态成员函数的地址时不允许使用括号的原因是什么?我在 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;

}

错误:main.cpp:14: 错误:ISO C++ 禁止采用未限定或带括号的非静态成员函数的地址来形成指向成员函数的指针。说“&myfoo::foo”

I found something interesting. The error message says it all. What is the reason behind not allowing parentheses while taking the address of a non-static member function? I compiled it on 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;

}

Error: main.cpp:14: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&myfoo::foo'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

惯饮孤独 2024-12-07 17:39:03

从错误消息来看,似乎不允许您获取带括号的表达式的地址。建议您重写

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

fPtr = &myfoo::foo;

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

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

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

希望这有帮助!

From the error message, it looks like you're not allowed to take the address of a parenthesized expression. It's suggesting that you rewrite

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

to

fPtr = &myfoo::foo;

This is due to a portion of the spec (§5.3.1/3) that reads

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses [...]

(my emphasis). I'm not sure why this is a rule (and I didn't actually know this until now), but this seems to be what the compiler is complaining about.

Hope this helps!

铜锣湾横着走 2024-12-07 17:39:03

想象一下这段代码:

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);
  }
};

如果没有括号的技巧,您将无法直接获取 B 的数据成员的指针(您将需要基类转换和带有 this 的游戏 - 不太好)。


来自ARM:

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

void B::f() {
    int B::* p = &B::i; // 好的
    p = B::i; // 错误:B::i 是 int
    p = &i; // 错误:'&i' 意味着 '&this->i' 是一个 'int*'

    int *q = &i; // 好的
    q = B::i; // 错误:'B::i 是一个 int
    q = &B::i; // 错误:'&B::i' 是 'int B::*'
}

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

Imagine this code:

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);
  }
};

Without the trick with the parentheses, you would not be able to take a pointer directly to B's data member (you would need base-class casts and games with this - not nice).


From the ARM:

Note that the address-of operator must be explicitly used to get a pointer to member; there is no implicit conversion ... Had there been, we would have an ambiguity in the context of a member function ... For example,

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::*'
}

The IS just kept this pre-Standard concept and explicitly mentioned that parentheses make it so that you don't get a pointer to member.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文