82

I'm trying to do some testing with member function pointer. What is wrong with this code? The bigCat.*pcat(); statement doesn't compile.

class cat {
public:
   void walk() {
      printf("cat is walking \n");
   }
};

int main(){
   cat bigCat;
   void (cat::*pcat)();
   pcat = &cat::walk;
   bigCat.*pcat();
}

2 Answers 2

143

More parentheses are required:

(bigCat.*pcat)();
^            ^

The function call (()) has higher precedence than the pointer-to-member binding operator (.*). The unary operators have higher precedence than the binary operators.

Sign up to request clarification or add additional context in comments.

11 Comments

@AdrianCornish: Nope, but pcat does not name a member, it names the pointer-to-member declared as a local variable in main.
I guess it is a little like a virtual function call - Is there a good use case/problem this is good for - struggling to think how to use this for good code
@AdrianCornish: I have never actually used this feature, nor have I seen it used in code written by others. Surely it has been used by someone... but the use cases are few and far between.
@AdrianCornish: It's a rarely used feature. I used it a lot in generic code, for example, I had a set of for_each-like algorithms that took a sequence of pointers and called a member function on each of the pointed-to objects. It saved me from having to use ugly function binder incantations. That was before lambda expressions made that a lot easier... if I were to rewrite all of that code, I'd probably use lambdas for most of the uses.
I find myself using it when refactoring and I see the same logic before and after a member-function call repeated again and again. That can get refactored into a function that takes a member function pointer to call so the before and after logic can be written only once.
|
18

Today, the canonical way is using the std::invoke function template, especially in generic code. Please note, that the member function pointer comes first:

import <functional>;

std::invoke(pcat, bigCat);

What you get: Unified calling syntax for virtually anything, that is invocable.

Overhead: none.

1 Comment

Caveat: requires C++17 (increasingly less of a problem of course)

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.