Search code examples
c++instant

How do I get a value from a class table in C++


Basically, I have a class in C++

class Commands { public: void help(); void userid(); void getCmd(std::string cmd) { } };
void Commands::help() {
    WriteLine("\n \
        --------------------------------\n \
        [ userid, id ]: Get's the UserID of your player\n \
        [ placeid, game ]: Get's the game ID\n \
        --------------------------------\n \
        \
    ");
}
void Commands::userid() {
    WriteLine("Your UserId is: 12345678");
}

I have a while(true) loop that runs a function which checks what the user responds with [ like a command based console ] I was wondering how I could do this:

Commands cmds;
cmds["help"]();
cmds["examplecmdhere"]();

When I try to do it I get an error Severity Code Description Project File Line Suppression State Error (active) E0349 no operator "[]" matches these operands Command


Solution

  • Use std::map or std::unordered_map to map std::strings to std::function that represent the functions to be called, then overload operator[] to provide easy access to the map without exposing the map.

    #include <string>
    #include <map>
    #include <functional>
    #include <iostream>
    class Commands { 
        // added: a map of strings to the function to call. private to keep 
        // unwanted hands off
        std::map<std::string, std::function<void()>> cmds = { 
            {
                "help", // Name of command
                [this](){ help(); } //Lambda expression that captures instance pointer
                                    // and uses it to invoke help function 
            } 
        };
    public: 
        void help(); 
        void userid(); 
        void getCmd(std::string cmd) { } 
        // added: overload the [] operator to give access to the map defined earlier
        auto & operator[](const std::string & cmd)
        {
            return cmds[cmd];
        }
    private:
    
    };
    void Commands::help() {
        // I have no WriteLine function, so I'm subbing in `std::cout for 
        // demonstration purposes
        std::cout << "\n \
            --------------------------------\n \
            [ userid, id ]: Get's the UserID of your player\n \
            [ placeid, game ]: Get's the game ID\n \
            --------------------------------\n \
            \
        ";
    }
    
    int main()
    {
        Commands commands;
        commands["help"](); //use operator[] to call help function
    }
    

    Result:

    
             --------------------------------
             [ userid, id ]: Get's the UserID of your player
             [ placeid, game ]: Get's the game ID
             --------------------------------
                 
    

    See it in action: https://godbolt.org/z/Kh39jqq3T