Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Pointer to function call not in scope

I have spent the last 3 hours trying to figure out what I am doing wrong. I just need some other eyes on this, I have tried everything I can think of, even various random permutations in an attempt to get the compiler to tell me something useful.

Here is where I am at now:

Code:

class villain
{
public:
   villain();
   //lots of other stuff
   bool Type1EnemyBlasts();
   bool Type2EnemyBlasts();
   bool (villain::*OnFire)();
};

villain::villain()
{
    //lots of other stuff
    OnFire = &villain::Type1EnemyBlasts;
}

main
{
    //lots and lots of other stuff
    villain *targets[100];
    targets[0] = new villain();
    if(targets[0]->*OnFire() == true)
    {
         //do stuff
    }
}

The error occurs when I call "targets[0]->*OnFire()", where it states that it is not declared in this scope. It feels weird to me that I have to define "OnFire" with "&villain::" when it is being defined inside the villain contructor, but all the information I have found suggests that it must be done this way, and indeed it churns up a whole plethora of errors if I try otherwise.

What is the proper syntax for calling the *OnFire() pointer that belongs to targets[0]?

like image 894
user3542913 Avatar asked Apr 16 '14 20:04

user3542913


2 Answers

The syntax for calling a pointer to member function is rather atrocious. Here's the correct syntax:

if ((targets[0]->*(targets[0]->OnFire))() == true)

That is downright ugly. This is why the Parashift C++ FAQ page on calling pointers to member functions recommends defining a macro for this purpose -- and note that the author of those pages dislikes macros.

#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

...

 if (CALL_MEMBER_FN(*targets[0],targets[0]->OnFire)() == true)

Either use a macro or use a std::function as described in sehe's answer.

like image 169
David Hammen Avatar answered Oct 14 '22 19:10

David Hammen


Change

if(targets[0]->*OnFire() == true)

to

if((targets[0]->*(targets[0]->OnFire))() == true)

Since the function call operator, (), has higher precedence than ->*, the first form is interpreted as:

if(targets[0]->*(OnFire()) == true)

which, as you can see, is not what you want.

like image 24
R Sahu Avatar answered Oct 14 '22 18:10

R Sahu