2012-02-06 15 views
6

Ecco il codice che causa l'errore:nessuna funzione membro corrispondente per la chiamata a 'cancellare'

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 
} 

E l'errore che ottengo:

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

Qualsiasi suggerimenti? Grazie.

+0

Qual è la necessità di 'it2'? Che ne dite di '_table.erase (it ++)'? – iammilind

risposta

7

Ecco la firma del map::erase in C++ 98:

void erase(iterator position); 

Questa funzione prende un iterator ma si sta passando un const_iterator. Ecco perché il codice non verrà compilato.

How do I fix this?

In C++ 11 questo non è nemmeno un problema, quindi non ha bisogno di essere riparato. Questo perché in C++ 11 la funzione map::erase ha la seguente firma e accetta quindi uno const_iterator.

iterator erase(const_iterator position); 

Se non è possibile utilizzare il nuovo standard, dovrete cambiare le variabili per iterator invece.

+0

Grazie. Mi stavo strappando i capelli. – ontherocks

+0

Come si passa un iteratore? Codice di esempio per favore? – JackKalish

+0

@JackKalish Er .... 'm.erase (it)'? –

2

vedere ciò che il maestro dice:

Scot Meyers in STL efficace

Articolo 26. Preferisco iteratore iteratore const, reverse_iterator e const_reverse_iterator. Sebbene i contenitori supportino quattro tipi di iteratore, uno di questi tipi ha privilegi che gli altri non hanno. Quel tipo è iteratore, iteratore è speciale.

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 

Articolo 27. Usare la distanza e anticipo per convertire const_iterators di un contenitore per iteratori.

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 

Che cosa funziona è anticipato e la distanza

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) 
Problemi correlati