3

I set up this account mainly because I couldn't find answers elsewhere. I checked, various tutorials or questions/ answers on stackoverflow and different pages.

I'm programming a terminal based textadventure and need a map of functions. This is what I got (I left out all the stuff that isn't of interesting for the problem)

#include <map>

using namespace std;

class CPlayer
{
private:

    //Players functions:
    typedef void(CPlayer::*m_PlayerFunction)(void); //Function-pointer points to various player 
                                                    //functions
    map<char*, m_PlayerFunction> *m_FunctionMap;    //Map containing all player functions

public:
    //Constructor
    CPlayer(char* chName, CRoom* curRoom, CInventory* Inventory);


    //Functions:
    bool useFunction(char* chPlayerCommand);
    void showDoors(); //Function displaing all doors in the room
    void showPeople(); //Function displaying all people in the room


};

#endif
#include "CPlayer.h"
#include <iostream>


CPlayer::CPlayer(char chName[128], CRoom* curRoom, CInventory *Inventory)
{
    //Players functions
    m_FunctionMap = new map<char*, CPlayer::m_PlayerFunction>;
    m_FunctionMap->insert(std::make_pair((char*)"show doors", &CPlayer::showDoors));
    m_FunctionMap->insert(std::make_pair((char*)"show people", &CPlayer::showPeople));
}






//Functions

//useFunction, calls fitting function, return "false", when no function ist found
bool CPlayer::useFunction(char* chPlayerCommand)
{
    CFunctions F;
    map<char*, m_PlayerFunction>::iterator it = m_FunctionMap->begin();

    for(it; it!=m_FunctionMap->end(); it++)
    {
        if(F.compare(chPlayerCommand, it->first) == true)
        {
            cout << "Hallo" << endl;
            (it->*second)();
        }
    }

    return false;
}

Now, the problem is the following:

If I call the function this way: (it->*second)(); which seems to be how it is supposed to be done, I get the following error: error: ‘second’ was not declared in this scope

If I call the function this way: (*it->second)(); which is what I got from this thread: Using a STL map of function pointers, I get following error: error: invalid use of unary ‘ * ’ on pointer to member

I'd be very glad if someone could help me. Thanks ahead for all the upcoming answers.

PS: It would also be interesting to know whether "map" or "unordered_map" is the better way of solving this problem.

As I said, thanks ahead: GB

Ben Steffan
  • 1,095
  • 12
  • 16
georgbüchner
  • 33
  • 1
  • 5
  • 1
    Possible duplicate of [How do I call a member function pointer?](https://stackoverflow.com/questions/24325612/how-do-i-call-a-member-function-pointer) – alain Jun 21 '17 at 14:27
  • Did the proposed duplicate question or searching for "calling pointer to member function" help you solve the problem? – nwp Jun 21 '17 at 14:37
  • 2
    There is issue with using `const char *` as key in a map. And there is no reason to make it worse casting it to `char *` – Slava Jun 21 '17 at 14:42
  • 1
    Using pointers as map keys is very unlikely to work well. And iterating over a map looking for a key is not the way to use a map. – molbdnilo Jun 21 '17 at 14:58
  • I don't think that's an exact duplicate of the above question. There are two operators `->*` and `.*`, and these two questions cover each one of them. – Ghislain Fourny Jun 21 '17 at 14:58
  • what about std::function? Also, why using new? – The Techel Jun 21 '17 at 15:06
  • You need a `std::unordered_map`, and hold it by value! That way you can just do `auto it = m_FunctionMap.find(chPlayerCommand); if (it != m_FunctionMap.end()) (this->*(it->second))();` – Martin Bonner supports Monica Jun 21 '17 at 16:22
  • Reason I'm using char*, is that the player Command might also contain people, items, door or room names, which are also char*, as they might change during the game, thus char* not const char. – georgbüchner Jun 22 '17 at 07:50

1 Answers1

2

The difficulty may be that it is at the same time a map, and it involves pointer-to-members, which makes the syntax to invoke more complicated with lots of parentheses that must be at the right positions. I think it should be something like this:

(this->*(it->second))()

Alternatively, as Rakete1111 points out, the following works as well:

(this->*it->second)()

(Note that the latter is less verbose, but also less easy to read for people who do not have the operator precedence on the top of their minds).

Ghislain Fourny
  • 6,971
  • 1
  • 30
  • 37