-2

I have made a mapping between string and a class type Person as mentioned in my earlier question using the following code.

std::map<std::string, Person*> person_list;
// while...
Person* person = University::addInput(person_type, person_name); //person_type: EMPLOYEE, ALUMNI, STUDENT
person_list[person_name] = person;

Problem: If the Person type is ALUMNI then it should be connected with another person of type STUDENT who's name has already been mapped before. Now, i want to connect these two persons.

I am trying to find the student_name (which is a key in this mapping scheme) but don't understand the correct way to do so.

PS: To remove the unnecessary confusion,i removed the find() problem. My real task is to find the mapped object at given key. So, i thought that find() could help me. But if there is some other method..please suggest me

Community
  • 1
  • 1
skm
  • 5,015
  • 8
  • 43
  • 104
  • Um... the error message seems to indicate the error isn't actually on that line. And please make your question self contained. – Cubic Apr 24 '14 at 17:25
  • @Cubic: Ok, i have put a short running version of my problem. Please have a look. – skm Apr 24 '14 at 17:36
  • 1
    What do you wish to see as the result of `cout<<(person_list.find("Tim"));`? This is clearly an attempt to do something but the compiler is not allowing you to do it. – R Sahu Apr 24 '14 at 17:42
  • @RSahu: At which location the name is present – skm Apr 24 '14 at 17:42
  • @RSahu: Actually my real task is to find the mapped object at given key. So, i thought that `find()` could help me. But if there is some other method..please suggest me – skm Apr 24 '14 at 17:44
  • to get the value of a certain key in a map, you just need to use `map[key]`. – Red Alert Apr 24 '14 at 17:50
  • @skm: As you demonstrate in your own code, `find` returns an iterator, and if the person is not in the map, it returns an end iterator. I'm not sure why you're trying to output the iterator, because _that's_ the problem, not the `find`. – Mooing Duck Apr 24 '14 at 17:50
  • @RedAlert: Not if you want to tell if it's already there or not. – Mooing Duck Apr 24 '14 at 17:51
  • @MooingDuck He doesn't want to check if it exists, though, so `map[key]` suits his problem. If he wants to check for existence as well, he can use `map.at(key)` (as long as he catches the possible exception) – Red Alert Apr 24 '14 at 17:54
  • Show the definition of a Person type. I've also no idea what University::addInput(INPUT(), person_name) does either. It looks like you are asking others to do homework for you at this point. – shawn1874 Apr 24 '14 at 19:26
  • @shawn1874: I have already accepted the relevant answer. I am not asking the homework...i have put effort in it..i have provided code with my each question. Definition of `Person` is not at all required for this question. The question is related about how to access the value of `key` in mapping. – skm Apr 24 '14 at 19:55

4 Answers4

2

What you really wanted to write was something like this: if(person_list.find("Tim") == person_list.end()). find returns an interator that can't be converted to a bool implicitly.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • ok, i have updated my question. Actually, by giving the name, i need to find the `Person*` at that name. It was just an example. – skm Apr 24 '14 at 17:42
  • 1
    Your update doesn't do much good because now you are trying to stream the iterator to cout which makes no sense. Your first use of find was correct. Why are you struggling so much with the second one? It seems like you need to find based on the key, and then if found check something else within the person object to see the person type. However, the person type isn't defined in your example. – shawn1874 Apr 24 '14 at 17:47
1
 if(person_list.find("Tim")) // == node_list.end()

The above line is not correct. The result of find is an iterator. The error is telling you that it cannot convert an iterator into a bool implicitly. You need to compare it to the end iterator of the map. Of course after doing that you'll get the cout because obviously there is no person named Tim within the map.

shawn1874
  • 1,288
  • 1
  • 10
  • 26
  • Actually my real task is to find the mapped object at given key. So, i thought that find() could help me. But if there is some other method..please suggest me – skm Apr 24 '14 at 17:46
  • 1
    Based on that question find does help you. Your example and question are too vague. First, you haven't shown the definition of a person object. The example is putting uninitialized pointers within the map. The keys are "node1" and "node2" which are not names so I am not sure what you are trying to do. – shawn1874 Apr 24 '14 at 17:49
  • This answer no longer matches the code in the question – Mooing Duck Apr 24 '14 at 17:51
  • @shawn1874: thanks, i was confused with the use of `(person_list.find("Tim")` and your answer removed my confusion but my actual requirement was different for which i have already accepted the answer. – skm Apr 24 '14 at 19:58
0

There are two ways to accomplish what you want to:

  1. Look for "Tim" in your map. If it is found, output it to cout.

    std::map<std::string, char>::iterator found = person_list.find("Tim");
    if ( found != person_list.end() )
    {
       std::cout << found->second << std::endl;
    }
    
  2. Assume "Tim" exists in the map, and access it's value using the [] operator.

    std::cout << person_list["Tim"] << std::endl;
    
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • if "Tim" isn't there then you'll just be printing an uninitialized pointer right? I'm not really sure what that would accomplish. – shawn1874 Apr 24 '14 at 19:24
  • @shawn1874, if "Tim" isn't there in the map, `person["Tim"]` returns an empty string. – R Sahu Apr 24 '14 at 19:30
  • Wrong. The map is of a string and a pointer. std::map person_list; found->second is a Person* or at least it is for now unless the question is changed again. The operator[] for map returns a reference to the second piece of the pair element which is a person* – shawn1874 Apr 24 '14 at 19:30
  • Nonetheless, your answer is on the right track given the udpate to the question. – shawn1874 Apr 24 '14 at 19:34
  • @shawn1874 for some reason, I thought the map in the OP was `map`. Am I hallucinating or did the OP change dramatically? – R Sahu Apr 24 '14 at 19:36
  • @RSahu: I have used your suggestion and it worked for me perfectly fine. In my case, i am mapping the `names` (string type) into `Person*` (pointer type). In the above question, i had `name` and i wanted to find its corresponding `Person*`. Now, i have the reverse question...i have `Person*` and i want to know its corresponding `name`..how can i do so? – skm Apr 25 '14 at 11:01
  • In that case you'll have to loop through the entire data structure, and compare to the mapped value until you find the one that you want, and then get the value of the associated key. There isn't built in functionality to the std::map to find a mapped value, only the key. Boost might have some bidirectional containers. – shawn1874 Apr 25 '14 at 21:56
  • @ R Sahu no you are not. The original question did change significantly. At one point there were two different map definitions. – shawn1874 Apr 25 '14 at 21:58
0

You can use the built in bounds checking of map.at() to you advantage:

try{
    Person* tim = person_list.at("Tim");
    /* do stuff with tim */
}
catch(const std::out_of_range& e){
    std::cout << "Tim not found!" << std::endl;
}
Red Alert
  • 3,786
  • 2
  • 17
  • 24