为什么不能使用成员指针取消引用来使用范围解析?

时间:2016-09-21 21:31:59

标签: c++ language-lawyer virtual-functions dereference member-pointers

考虑一个简单的例子:

struct FooParent {
   virtual void bar() { }
};

struct Foo: FooParent {
   void bar() { }
};

int main() {
   Foo foo;
   void (Foo::*foo_member)() = &FooParent::bar;
   //(foo.*FooParent::foo_member)();
   foo.FooParent::bar();
}

正如您所见,当调用bar成员函数时,可以在foo对象上使用范围解析,而无法显式声明成员函数指针的范围。我接受在使用->*时应禁止语法,因为运算符可能会以某种意外的方式重载,但我无法理解在使用.*解除引用时阻止显式范围解析的原因。

我正在尝试禁用指向基类的虚函数的成员指针的虚拟调度。

1 个答案:

答案 0 :(得分:4)

您声明的变量的名称是foo_member,位于您的本地块范围内。它不是 名称Foo::foo_member,即类Foo没有成员foo_member。相比之下,名称bar位于班级Foo的范围内,也位于班级FooParent的范围内。

因此,范围解析机制按预期工作:它解决了范围。

[ Update :]没有通过成员函数指针禁用虚拟分派的机制。您可以像这样调用基础子对象的成员函数:

 void (FooParent::*p)() = &FooParent::bar;
 (static_cast<FooParent&>(foo).*p)();

但是这个电话仍然会被虚拟派遣。成员函数的虚拟性被烘焙到成员函数指针值中。您可以做的下一件事是使用lambda:

auto q = [](FooParent & f) { f.FooParent::bar(); };
q(foo);