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 ? ?

13
  • use map::find to get an iterator to the element. Commented Feb 9, 2015 at 21:15
  • 1
    It's good form to write a SSCCE which has an example declaration of a map and the accessing of the map. Commented Feb 9, 2015 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 Commented Feb 9, 2015 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). Commented Feb 9, 2015 at 21:18
  • 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. Commented Feb 9, 2015 at 21:24

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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).

8 Comments

std::map::at() might be a good alternative too.
@juanchopanza: yes, but only in C++11 and later. Either way, find() returns an interator, which makes it easy to check if the element exists or not. But at() throws a std::out_of_range if the elements does not exist.
@RemyLebeau That's one before the current standard. We're in the year 2015 ;-)
@juanchopanza: Yes, but may C++ compliers still do not support C++11 yet, or only support portions of it.
@RemyLebeau Well, that could be an optional note in an answer. The question doesn't specify C++03, so I see no reason to restrict answers to old standards.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.