No Matching Member Function for Call to 'Erase'
Here's the Code That Causes the Error: Factory. H: #Include #Include Namespace Basesubsystems { Template Class Cfactory { Protected: Typedef T...
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.
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.
You are passing a const_iterator to a method which expects a plain iterator.
See:
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)