Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: no match for 'operator[]' in... <near match>

Tags:

c++

This fail to compile in gcc 4.1.2 / RedHat 5 :

#include <string>
#include <vector>
#include <map>

class Toto {
public:
    typedef std::string SegmentName;
};

class Titi {
public:
    typedef Toto::SegmentName SegmentName; // import this type in our name space
    typedef std::vector<SegmentName> SegmentNameList;
    SegmentNameList segmentNames_;
    typedef std::map<SegmentName, int> SegmentTypeContainer;
    SegmentTypeContainer segmentTypes_;

    int getNthSegmentType(unsigned int i) const {
        int result = -1;

       if(i < segmentNames_.size())
       {
           SegmentName name = segmentNames_[i];
           result = segmentTypes_[ name ];
       }
       return result;
    }
};

The error is :

error: no match for 'operator[]' in '(...)segmentTypes_[name]'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:340:
note: candidates are: _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&)
[with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = int, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >]

Why ? The map is rather straightforward. I guess this has to do with the typedefs, but what is wrong ?

[edit] Even if I remove all the typedefs and use std::string everywhere, the problem persists... Am I misusing maps ?

like image 773
Offirmo Avatar asked Mar 27 '13 14:03

Offirmo


2 Answers

std::map::operator[] is non-const and you're trying to use it from a const method.

You could achieve this using std::map::find, which returns a const_iterator:

SegmentTypeContainer::const_iterator iter = segmentTypes_.find(name);

If you're using C++11, you could also use std::map::at, which will throw an exception if the key is not found in the map:

result = segmentTypes_.at(name);
like image 191
mfontanini Avatar answered Nov 04 '22 23:11

mfontanini


std::map::operator[] is not a const method, but you are calling it from a const method of your class. The reason for this is that it adds an element if the key is not present.

You can use C++11 at():

result = segmentTypes_.at(name); // throws exception if key not present.

or use std::map::find.

SegmentTypeContainer::const_iterator it = segmentTypes_.find(name);
if (it != segmentTypes_.end())
{
  // OK, element with key name is present
  result = it->second;
}
like image 38
juanchopanza Avatar answered Nov 05 '22 01:11

juanchopanza