2

Consider a simple example:

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

As you can see one can use scope resolution on the foo object when calling bar member function while there is no way to explicitly declare the scope for member function pointer. I accept that the syntax should be prohibited when using ->* as the operator can be overloaded in sometimes unexpected way, but I cannot understand the reason behind preventing explicit scope resolution when dereferencing with .*.

I am trying to disable virtual dispatch for a member pointer that points to a base class's virtual function.

0

1 Answer 1

5

The name of the variable you declared is foo_member, inside your local block scope. It is not a name Foo::foo_member, i.e. the class Foo has no member foo_member. By contrast, the name bar lives in the scope of the class Foo, and also in the scope of the class FooParent.

So the scope resolution mechanism works as expected: it resolves the scope.

[Update:] There is no mechanism to disable virtual dispatch through a member function pointer. You can call a member function of the base subobject like this:

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

But the call still ends up getting dispatched virtually. The virtuality of the member function is baked into the member function pointer value. The next best thing you can do is to use a lambda:

auto q = [](FooParent & f) { f.FooParent::bar(); };
q(foo);
Sign up to request clarification or add additional context in comments.

9 Comments

So in other words the reason lays in precedence of the scope operator?
@W.F.: Not at all. The reason is that the purpose of the scope resolution is to resolve scopes, but foo_member is already in the current scope, and not in the scope of FooParent. So if anything, the reason is perhaps your misunderstanding of the concept of a "scope".
Oh, wait, now I understand what you want to do: You want to perform the direct, static base function call without the virtual dispatch. I didn't get that in your original question. Let me think about that.
@W.F.: I suppose it's the other way round: The feature to disable the virtual call mechanism only exists in the limited form of using the explicit qualification in the class member access expression, but not in the pointer-to-member expressions. (If you think that's a really useful and necessary feature, feel free to propose it as a language extension.)
@W.F.: If you can, please keep track of how often this particular problem comes up over the next, say, three years. If you feel that the language would be significantly enriched if this were a feature, it's entirely feasible to propose this as an extension. We'd mostly want to see good motivating cases where the existing solution is either unbearably worse, or where a core language feature would make code less error prone and easier to understand.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.