1

say i have a method as this

int someclass::somemethod(const std::string &name) const
{
       std::string a = mymap["a"];
       ..... 
}

where mymap

std::map<std::string,std::string> 

This is the error i get

Error   1   error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<std::string, std::string>   ' (or there is no acceptable conversion)    

Any suggestions on how i can access value of a key ? ?

MistyD
  • 16,373
  • 40
  • 138
  • 240
  • use map::find to get an iterator to the element. – Beginner Feb 09 '15 at 21:15
  • 1
    It's good form to write a [SSCCE](http://www.sscce.org/) which has an example declaration of a map and the accessing of the map. – Sam I am says Reinstate Monica Feb 09 '15 at 21:16
  • I know i could do that however for some crazyy reason the map is returning end() and I am certain the item is in the container. Thats why i wanted to use the [] operator – MistyD Feb 09 '15 at 21:17
  • 1
    Using `operator[]` to do the search won't help. Either the names match (in which case `find` will work fine) or else they don't (in which case `[]` will insert a *new* node with the new key and a value-initialized mapped value--an empty string in this case). – Jerry Coffin Feb 09 '15 at 21:18
  • @SamIam its not a complicated example. Create a method inside a class with const and test it out. What i gave here makes clear sense and on top of that i explicitly stated that this problem is because of a const mehtod – MistyD Feb 09 '15 at 21:19
  • @Beginner: Not really, no. – Lightness Races in Orbit Feb 09 '15 at 21:22
  • @MistyD when asking a question it's up to you to provide the full example - help others to help you . In this case it turns out that experienced answerers can identify a likely cause of error just based on the error message, but that's not always true; and the "most likely answer based on the error message" is not always the actual root of the problem. – M.M Feb 09 '15 at 21:23
  • 1
    @MistyD I'm not completely familiar with this problem and this problem might be able to be identified without a SSCCE, but there are many cases where users ask questions giving segmented code blocks(like you are) where the **real problem** exists **outside** of the provided code. for future reference, it's normally a good idea to make one when the problem is this simple to reproduce. – Sam I am says Reinstate Monica Feb 09 '15 at 21:24
  • @LightnessRacesinOrbit looks identical to me. OP didn't bother to show the actual code; perhaps the `map` in question is `const` by virtue of being a class member in a `const` function , or declared `const` (as opposed to coming in via a parameter), but the problem and solution are the same – M.M Feb 09 '15 at 21:25
  • @MattMcNabb: Mate the code's right there in the question. The map is `const` by virtue of being a class member in a `const` function, which is different from the question you linked to, ergo, not a "duplicate". – Lightness Races in Orbit Feb 09 '15 at 21:31
  • @LightnessRacesinOrbit you seem to be assuming `mymap` is a member of `someclass`; this is not stated in the question. IMO it is a duplicate despite this minor detail. To be marked "duplicate" it doesn't have to be word for word identical. – M.M Feb 09 '15 at 21:34
  • @MattMcNabb: http://www.thefreedictionary.com/duplicate Cheers – Lightness Races in Orbit Feb 09 '15 at 21:35
  • good thing that thefreedictionary isn't in charge of SO site policy then eh? – M.M Feb 09 '15 at 21:36

2 Answers2

7

Use map's .find member function to do the search.

auto it = mymap.find("a");

if (it != mymap.end())
    // it->first = key, it->second = mapped value.

Using operator[] instead of find won't make the search work any better. Either the keys match (in which case find will work just fine) or else they don't (in which case [] attempts to insert a new node with that key, which will be associated with a value-initialized value--an empty string in this case.

It's that latter behavior (inserting the new node) that means there's no const version of operator[].

Yes, it would have been possible to define operator[] in a way that worked with a const container, such as throwing an exception when/if the requested key wasn't present--but it's not defined to work that way now, and probably won't be any time soon either.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
6

The std::map::operator[] has a (evil (!?)) non-constant side effect. The operator adds a new element if that element does not already exist. somemethod() is declared as const, so the std::map is also const and cannot be modified. Hence, the non-constant operator[] can not be applied to the const std::map. Alternatives are std::map::find() and std::map::at() (C++11).