Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

called object type 'void (B::*)(int)' is not a function or function pointer

I am trying to wrap my head around passing method as function argument. Here is a simplified example which returns a compilation error that I don't understand

class B
{
private:
    int j;
public:
    void foo(int i){std::cout << i + this->j << std::endl;}
    void setj(int J){j=J;}
};

class A
{
private:
    B b;

public:
    void call(void (B::*fun)(int i), int i) { b.*fun(i); }
    void setBj(int j){b.setj(j);}
};


int main()
{
    A a;
    a.setBj(40);
    a.call(B::foo, 2);
}

When compiled with

g++ -std=c++11 b.cpp -o b

I get

b.cpp:22:50: error: called object type 'void (B::*)(int)' is not a function or
      function pointer
        void call(void (B::*fun)(int i), int i) { b.*fun(i); }
                                                     ~~~^
b.cpp:31:12: error: call to non-static member function without an object
      argument
        a.call(B::foo, 2);
               ~~~^~~
2 errors generated.

I don't understand the first error message. I understand that I am calling foo as if it was a static method, which it is not but I don't understand how to pass a non-static method.

like image 229
Remi.b Avatar asked Dec 20 '17 10:12

Remi.b


1 Answers

Two problems.

  1. To invoke a pointer to a member function, you need to first apply a pointer to member access operator, that obtains a callable expression. Then you add a call. Now it just so happens that .* is of lower precedence than the function call operator. So the first fix:

    (b.*fun)(i)
    
  2. A a pointer to member function can only be obtained by applying unary & on the fully qualified function name. So the second fix:

    a.call(&B::foo, 2);
    
like image 154
StoryTeller - Unslander Monica Avatar answered Oct 17 '22 13:10

StoryTeller - Unslander Monica