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:

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest