Home > Net >  Creating an Array of pointers to member functions
Creating an Array of pointers to member functions

Time:01-26

In short, I tried searching on how to do this, but I seem to be missing something. One constraint to my problem: Human.h cannot change. We must operate with what we've been given. I am also told to create the array of pointers to members to decide on which function needs to be called.

Here's what I have:

Human.h

class Human
{
private:
    void meleeAttack(std::string const& target);
    void rangedAttack(std::string const& target);
    void intimidatingShout(std::string const& target);
public:
    void action(std::string const& action_name, std::string const& target);
};

Human.cpp

#include "Human.h"

typedef void (Human::* Human_mem_fnPtr)(std::string target);

void Human::meleeAttack(std::string const& target)
{
    std::cout << "Melee Attack performed on " << target << "!\n";
}

void Human::rangedAttack(std::string const& target)
{
    std::cout << "Ranged Attack performed on " << target << "!\n";
}

void Human::intimidatingShout(std::string const& target)
{
    std::cout << "Shout performed on " << target << "!\n";
}

void Human::action(std::string const& action_name, std::string const& target)
{
    //error on initialization--expression must be an lvalue or function designation--but they ARE func designations...
    Human_mem_fnPtr fnPtr[] = {&Human::meleeAttack(target), &Human::rangedAttack(target), &Human::intimidatingShout(target)}; 
}

From what I found online, I am going in the right direction here. What am I missing?

CodePudding user response:

A couple of points:

  • Doing pointers to functions is made much easier with the std::function<> template class.
  • Using a old-style array is not really the best choice these days.

A map or unordered_map would be a much better option, with a definition like this:

using ActionMap = std::unordered_map<const std::string, std::function<void(const std::string&)>;

When adding your functions to this map you would use something like the following:

mActionMap["rangedAttack"] =  std::mem_fn(&Human::rangedAttack);

This will give you a cleaner and easier to maintain option and should compile cleanly.

Note that the std::mem_fn is required to wrap a member function of a class.

Edit: Per your comment below, Id still suggest using as many of the modern C constructs as possible.

using ActionFunc = std::function<void(const std::string&)>;

And then:

ActionFunc actions[] = { std::mem_fn(&Human::rangedAttack), ...}

or:

std::array<ActionFunc> actions = ...

  •  Tags:  
  • c
  • Related