нет функции-члена для вызова "стереть"

вот код, который вызывает ошибку:

фабрики.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
}

и ошибка, которую я получаю:

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

какие-либо советы? Спасибо.

3 ответов


вот подпись map::erase в C++98:

void erase( iterator position );

эта функция принимает iterator но вы проходите const_iterator. Вот почему код не компилируется.

как это исправить?

в C++11 это даже не проблема, поэтому ее не нужно исправлять. Это потому, что в C++11 map::erase функция имеет следующую подпись и, таким образом, принимает const_iterator.

iterator erase( const_iterator position );

если вы не можете использовать новый стандарт, вам придется изменить переменные на .


вы передаете const_iterator методу, который ожидает простой итератор.

см.:http://www.cplusplus.com/reference/stl/map/erase/


смотрите, что говорит мастер:

шотландец Мейерс в эффективном STL

пункт 26. Предпочитаю итератор константный итератор, итератор reverse_iterator, и const_reverse_iterator. Хотя контейнеры поддерживают четыре типа итераторов, один из этих типов имеет права не имеют. Этот тип является iterator, iterator является специальным.

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

пункт 27. Используйте distance и advance для преобразования const_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

что работает заранее и расстояние

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)