0

I have a std::map variable that contains a std::string as its first parameter and a struct for its second.

struct entry {
    std::string state;       // works like an url eg. "/login" shows login
    std::string description; // menu entry description eg. "login here"
    int minAuth;             // maximum user authorization level
    int maxAuth;             // minimum user authorization level
    void (*fptr)();          //function to be called on match
    bool active = false;     // true if this is one of the options displayed 
};

std::map<std::string, entry> entries;

What I need to check is the first parameters value and the second value (entry.active) in order to correctly display the menu entries. I'm using an active attribute to make sure that if there are other entries with the same std::string (this is the command to start the function entry.fptr), they won't have the same active state.

Explenation for the entry.active attribute:

eg. imagine two different pages; usersPanel and viewImage. Both of these have a command called "download", however they both have different functions. One downloads a log of users, and the other downloads an image. (this is just an example).

I would prefer to have a compare function that checks that the first parameter matches a given input, and that the entry.active is true.

What I'm trying to accomplish is something like the code below. This isn't a functional code, it's just to clearify how I want the compare() parameter to work. check if the input is similar to the key, and if the map entry has a value.active of true, I want the comp() to return true.

bool comp (const std::string a, const std::string b) const
{
    return (a == b && this.second.active);
}

Again, a few have complained about this piece of code so let me say it like this: thats psuedo code, not real code.

My second way to handle this would to have a temporary std::map for all the currently active menu entries, but I'm hoping I won't need to add an additional std::map list. The comp() would be so much cleaner.

Pastebin code: http://pastebin.com/1uj40Fw8

Any suggestions? ^^,

SOLUTION

add a extra map holder:

std::map<std::string, entry> entries, activeEntries;

After a map entry is approved by the program rules to be displayed, add it to the activeEntries map:

activeEntries.insert(i);

Then use std::map::find on the activeEntries map to locate the correct user choice, in the entire menu. Also more efficient for larger menus.

andersfylling
  • 718
  • 10
  • 24
  • Dot after `this` is not C++. What class is `comp` member of and how is it called? Why are you passing `a` and `b` by `const` value and not reference? – LogicStuff Apr 03 '16 at 17:28
  • I have no idea how I would implement the comp() function so that isn't really a suggestion, but rather a way to show you guys what I'm looking for. Anyways for my curiosity, would it be correct to use this->entry.active? – andersfylling Apr 03 '16 at 17:33
  • `this->` can be omitted altogether, it serves only for disambiguation and [different name lookup in derived class templates](http://stackoverflow.com/questions/4643074/why-do-i-have-to-access-template-base-class-members-through-the-this-pointer). – LogicStuff Apr 03 '16 at 17:35
  • Not sure what you're trying to do. – erip Apr 03 '16 at 17:47
  • look at the code example I wrote. something like that. – andersfylling Apr 03 '16 at 17:50
  • How are we supposed to divine what you want to do, from a broken code sample that doesn't do that thing? Explain it in _words_. – Lightness Races in Orbit Apr 03 '16 at 18:31
  • I was looking for a compare function to handle how std::map::find() works. However I do not know exactly how that would be done (now I know I can't), so using code I tried to explain better what I was trying to accomplish. I never said this is the code, and this works. thats why i wrote "Something like this perhaps?", ill update the format in hope to remove this confusion. – andersfylling Apr 03 '16 at 18:43
  • updated and added that its psuedo code, not a working code example. – andersfylling Apr 03 '16 at 18:47

1 Answers1

1

You cannot use value part for comparison function in std::map though it is technically possible, as key must not be changed when it is inside map. So you either have to keep multiple maps or you can use std::multimap instead, call std::multimap::equal_range and search for active value inside that range.

Note, you can change key to std::pair<std::string,bool> and duplicate active flag there, but I do not think that would help in your situation - to change key you have to remove your entry and reinsert it with modified key, which does not make much sense here.

Probably better and cleaner solution would to keep std::shared_ptr to entries in different maps depend on context, then you would not have to duplicate entries and you do not actually need active flag - just add to a map where it should be active.

Slava
  • 43,454
  • 1
  • 47
  • 90