Reputation: 164
I have looked at several post about const qualifiers, but I am not able to figure out how to fix this issue. I am building a class that is modeled after the STL map class, and I am using the STL set class as the base class:
template <class Key, class Value>
class map : public std::set <std::pair<Key, Value> > {
public:
typedef std::set<std::pair<Key, Value> > parent;
typedef typename std::set<std::pair<Key, Value> >::iterator iterator;
// constructors
map() : parent() {}
map(map<Key, Value>& m) : parent(m) {}
// definition for subscript operator
Value& operator [] (const Key &);
// overloaded methods from set
void erase(Key&);
void erase(iterator& itr) {
parent::erase(itr);
}
int count(Key&);
iterator find(Key&);
iterator lower_bound(Key& k) {
return parent::lower_bound(k);
}
iterator upper_bound(Key& k) {
return parent::upper_bound(k);
}
// not found iterator
iterator end() {
return parent::end();
}
};
The problem is with the operator[] overload function, which looks like:
template <class Key, class Value>
Value& map<Key, Value>::operator[] (const Key& k) {
std::pair<Key, Value> test;
test.first = k;
std::pair<iterator, bool> where = parent::insert(test);
return (*(where.first)).second;
}
The compiler is giving me the error "...map.h:108:16: Binding of reference to type 'int' to a value of type 'const int' drops qualifiers". I realize that it's seeing that (*(where.first)).second is evaluated to a "const int" and I am returning it to an "int" because I have declared a map as:
map<std::string, int> mymap;
mymap["one"] = 1;
It appears that the std::pair<...>
is being defined as std::pair<std::string, const int>
instead of std::pair<std::string, int>
. At least this is my conjecture. I must be missing something simple, but I am not seeing it. Any help is greatly appreciated.
Upvotes: 1
Views: 1918
Reputation: 272687
The issue is that std::set
elements are immutable (otherwise you could arbitrarily modify them and mess up the ordering without the set
knowing about it); this is enforced by its method returning const iterators.
Therefore, *(where.first)
is const
, and therefore so is (*(where.first)).second
. So you can't return a non-const
reference to it.
Upvotes: 3