Domanda

Ho bisogno di aiuto per comprendere alcune dichiarazioni di sovraccarico dell'operatore C ++. La classe è dichiarata così:

template <class key_t, class ipdc_t>
class ipdc_map_template_t : public ipdc_lockable_t
{
    ...
    typedef map<key_t,
            ipdc_t*,
            less<key_t>> map_t;
    ...

Il creatore della classe ha creato un iteratore per la struttura della mappa interna:

struct iterator : public map_t::iterator
{
    iterator() {}
    iterator(const map_t::iterator & it)
        : map_t::iterator(it) {}
    iterator(const iterator & it)
        : map_t::iterator(
            *static_cast<const map_t::iterator *>(&it)) {}
    operator key_t() {return ((this->operator*()).first);}           // I don't understand this.
    operator ipdc_t*() const {return ((this->operator*()).second);}  // or this.

};

E begin () e end () restituiscono begin () e end () della mappa:

iterator begin() {IT_ASSERT(is_owner()); return map.begin();}
iterator end() {return map.end();}

La mia domanda è, se ho un iteratore, come posso usare quei sovraccarichi per ottenere la chiave e il valore?

ipdc_map_template_t::iterator iter;
    for( iter = my_instance.begin();
             iter != my_instance.end();
         ++iter )
    {
        key_t my_key = ??????;
        ipdc_t *my_value = ??????;

    }
È stato utile?

Soluzione

Questi sono operatori di typecast, quindi puoi farlo:

{
    key_t   key = iter;
    ipdc_t *val = iter;
}

Oppure, poiché ipdc_map_template :: iterator è una sottoclasse di std :: map :: iterator , puoi comunque usare gli accessori originali (che trovo più leggibili) :

{
    key_t   key = (*iter).first;
    ipdc_t *val = (*iter).second;

    // or, equivalently
    key_t   key = iter->first;
    ipdc_t *val = iter->second;

}

Altri suggerimenti

operatore key_t () e operatore ipdc_t * () sono entrambe definizioni di cast. Quindi, dato un iteratore come definito nella classe, dovresti essere in grado di assegnare semplicemente le tue variabili:

ipdc_map_template_t::iterator iter;
    for( iter = my_instance.begin();
         iter != my_instance.end();
         ++iter )
    {
            key_t my_key = iter;
            ipdc_t my_value = iter;
    }

Il creatore della classe ha ignorato gli operatori del cast. Quindi, semplicemente assegnando l'iter a un oggetto del tipo corretto, dovrebbe automaticamente lanciare se stesso tramite i metodi nei valori corretti.

N.B. : il tipo di valore viene archiviato come puntatore. Pertanto, quando si estrae il valore, è necessario specificare il puntatore al tipo di valore specificato nell'interfaccia della mappa.

 typedef ipdc_map_template_t<int,std::string>   MyMap;
 MyMap    mymap;

 for(MyMap::iterator iter = mymap.begin();
                     iter != mymap.end();
                     ++iter )
    {
            int          my_key   = iter;
            std::string* my_value = iter;

    }

Non sono sicuro di essere d'accordo con la direzione presa qui. Questo rende il codice più leggibile? Vorrei rimanere con l'iteratore di mappe vecchio stile suona più utilizzabile. Questo contenitore viene definito in alcune librerie specializzate di cui hai bisogno o sarebbe utile esaminare i contenitori del puntatore boost?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top