1

AFAIK, in C++, invoking another member function within a member of function of the same class should not require the "this" prefix as it is implicit. However, in the specific case of using function pointers, the compiler requires it. The following code compiles correctly only if I include the "this" prefix for the call via func pointer -

When function pointers are used can the compiler deduce when it points a member func of the same class?

class FooBar { private: int foo; public: FooBar() { foo = 100; } int GetDiff(int bar) { return abs(foo - bar); } typedef int(FooBar::*MyFuncPtr)(int); void FooBar::Bar() { MyFuncPtr f = &FooBar::GetDiff; (this->*f)(10); GetDiff(10); } }; 
0

5 Answers 5

6

It's required, because member function pointers (which are not the same thing as function pointers) are not bound, and you can use them with different objects.

(this->*f)(10); (foo.*f)(10); // etc. 
Sign up to request clarification or add additional context in comments.

1 Comment

Member functions (not pointers) also need to be applied to one object, but if no object is given (and we are in a member function of the same class) an implicit this-> is added by the compiler. I believe the question is why the difference.
2

When you invoke an instances member function the this pointer is implicitely put to the function parameters. Thus you need to specify this also when invoking that function via a function pointer.

f isn't a member of the class, but a local variable, you could also specify another instance pointer instead of this, so the compiler can't deduce that. Same for member function pointers as class member variables.

Comments

1

The simple question is that it is a matter of language design and the language was designed this way.

Inside a member function, and to ease the common syntax when the compiler encounters an identifier it performs lookup starting from this class (plus ADL on the arguments), and if the lookup finds an unambiguous non-static member of this type (or of a base type) then the compiler will inject this-> for you (that is, applies operator-> to the this pointer).

In the case of a pointer to member the process is quite different. The pointer (which is not really a pointer, but for the sake of argument) is found by lookup, but it is your responsibility to provide the object on which it will be called and use the appropriate operator (either .* for calling a pointer to member on a reference, or ->* for calling the member on a pointer).

Note that the operators that are called are different, and that the process is different altogether (in one case lookup finds a member, in the other it finds a variable that happens to be pointer-to-member), but the most important part is that calling pointers to members is infrequent enough, and calling them on this is even less frequent that it does not not to warrant an exemption on the syntax for a small use case.

Comments

0

f isn't a member of FooBar. So if you want to call f on an instance of FooBar, you have to tell it which instance.

In your example, f does contain a member of FooBar, but the compiler doesn't know that.

Comments

0

This happens because of the way the C++ runtime handles classes while you are not looking. Basically it would be inefficient to store the function pointers in the instance, so the compiler builds a class specific table with function pointers that have the same arity as the member functions you defined and that get the this pointer passed at runtime (AFAIK visualc passes the pointer via ecx, I'm not entirely sure what happens on GCC)

So basically when you do

instance->foo(10); 

You are telling the runtime to call function foo with the parameter 10 and pass (instance) as the this pointer, wich is why you have to specifically say which object it has to be called on.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.