BlogInfo

no matching member function for call to 'erase'

Here's the code that causes the error:

Factory.h:

#include <string> #include <map> namespace BaseSubsystems { template <class T> class CFactory { protected: typedef T (*FunctionPointer)(); typedef std::pair<std::string,FunctionPointer> TStringFunctionPointerPair; typedef std::map<std::string,FunctionPointer> TFunctionPointerMap; TFunctionPointerMap _table; public: CFactory () {} virtual ~CFactory(); }; // class CFactory template <class T> inline CFactory<T>::~CFactory() { TFunctionPointerMap::const_iterator it = _table.begin(); TFunctionPointerMap::const_iterator it2; while( it != _table.end() ) { it2 = it; it++; _table.erase(it2); } } // ~CFactory } 

And the error I get:

error: no matching member function for call to 'erase' [3] _table.erase(it2); ~~~~~~~^~~~~ 

Any tips? Thanks.

1

3 Answers

Here's the signature of map::erase in C++98:

void erase( iterator position ); 

This function takes an iterator but you're passing a const_iterator. That's why the code won't compile.

How do I fix this?

In C++11 this isn't even a problem, so it doesn't need fixing. That's because in C++11 the map::erase function has the following signature, and thus accepts a const_iterator.

iterator erase( const_iterator position ); 

If you can't use the new standard, you'll have to change your variables to iterator instead.

1

You are passing a const_iterator to a method which expects a plain iterator.

See: http://www.cplusplus.com/reference/stl/map/erase/

See what the master says:

Scot Meyers in Effective STL

Item 26. Prefer iterator to const iterator, reverse_iterator, and const_reverse_iterator. Though containers support four iterator types, one of those types has privileges the others do not have. That type is iterator, iterator is special.

typedef deque<int> IntDeque; //STL container and typedef lntDeque::iterator Iter; // iterator types are easier typedef lntDeque::const_iterator ConstIter; // to work with if you // use some typedefs Iter i; ConstIter ci; … //make i and ci point into // the same container if (i == ci ) ... //compare an iterator // and a const_iterator 

Item 27. Use distance and advance to convert a container's const_iterators to iterators.

typedef deque<int> IntDeque; //convenience typedefs typedef lntDeque::iterator Iter; typedef lntDeque::const_iterator ConstIter; ConstIter ci; // ci is a const_iterator … Iter i(ci); // error! no implicit conversion from // const_iterator to iterator Iter i(const_cast<Iter>(ci)); // still an error! can't cast a // const_iterator to an iterator 

What works is advance and distance

typedef deque<int> IntDeque; //as before typedef IntDeque::iterator Iter; typedef IntDeque::const_iterator ConstIter; IntDeque d; ConstIter ci; … // make ci point into d Iter i(d.begin()); // initialize i to d.begin() Advance(i, distance(i, ci)) //move i up to where ci is // (but see below for why this must // be tweaked before it will compile) 

ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJocGptZWd9eHvNqGSmmaSYtaq6xmaknqWSmr9ustSnmq2hn6N6p7vRZpqapJxiwbB5xKuYrJ0%3D

Mittie Cheatwood

Update: 2024-06-30