Newsgroup: it.comp.lang.c++
Titolo: Problema con un iteratore

Salve a tutti,
sto scrivendo una piccola classe che racchiude un set. Vorrei avere un
metodo find() che e' praticamente un wrapper del find() del set, che mi
restituisca NULL se l'elemento non c'e', o un puntatore all'elemento se
c'e'.
Ho provato con 
template<typename ElemType>
const ElemType * ts_set<ElemType>::find(const ElemType & key) {
        set<ElemType>::iterator itr = theSet.find(key);
 
        if(itr == theSet.end())         // elemento non trovato
                return NULL;
        else
                return itr;
}
mi aspettavo problemi sul "return itr;" (come faccio a trasformare
l'iteratore in un puntatore?), invece non compila
"set<ElemType>::iterator itr"
mi dice "expected `;' before 'itr'".
Il problema sembra essere lo ElemType, infatti se per assurdo
scrivo "set<int>::iterator itr" compila.
Perche'?
Thx,
Pleg

PS: la classe ha come private
set<ElemType> theSet;

Pleg ha scritto:

Prova a fare:
typedef set<ElemType> Set;
Set::iterator itr;
E.

 }
 template<typename ElemType>
 const ElemType * ts_set<ElemType>::find(const ElemType & key) {
        typename set<ElemType>::iterator itr = theSet.find(key);
 
        if ( itr == theSet.end() )         // elemento non trovato
                return 0;
        else
                return &*itr;
 }
 
http://pages.cs.wisc.edu/~driscoll/typename.html
M

 return &*itr;
non e' la stessa cosa che castare l'iteratore ad un puntatore?
Pleg

Nuu! :-)
Quello che succede è che il template con la classe dell'iteratore fa
l'overriding di operator* e operator-> per ritornare il puntatore o
l'oggetto dereferenziato a cui l'iteratore si riferisce.
Quello che succede con:
   &*itr;
è:
   &(itr.operator*);
   &(ElemType);
Un cast non funzionerebbe, a meno che non sia definito manualmente
anche l'operatore di casting esplicito (e di solito non è un bene
farlo, perché rende il codice più difficile da leggere per chi non
l'ha scritto).
Spero di aver scritto correttamente perché è pronto da mangiare e sono
di super fretta, però l'idea è quella giusta :-p.
Ciao,
Matteo


 wrote in message 
news:c2b00ba4-2ab8-46f8...@o36g2000vbi.googlegroups.com...
Nuu! :-)
Quello che succede � che il template con la classe dell'iteratore fa
l'overriding di operator* e operator-> per ritornare il puntatore o
l'oggetto dereferenziato a cui l'iteratore si riferisce.
Quello che succede con:
   &*itr;
�:
   &(itr.operator*);
   &(ElemType);
Un cast non funzionerebbe, a meno che non sia definito manualmente
anche l'operatore di casting esplicito (e di solito non � un bene
farlo, perch� rende il codice pi� difficile da leggere per chi non
l'ha scritto).
Spero di aver scritto correttamente perch� � pronto da mangiare e sono
di super fretta, per� l'idea � quella giusta :-p.


 }
Ma itr non � gia un puntatore all'elemento?
Infatti ho provato questo codice:
#include <iostream>
#include <string>
#include <vector>
std::vector <std::string> v;
int main() {
    v.push_back("A");
    std::vector<std::string>::iterator it = v.begin();
    if (*it == *(&(*it))) {
       std::cout << *(&(*it)) << std::endl;
       std::cout << *it << std::endl;
    };
    return 0;
}
La condizione si verifica quindi vuol dire che it == &(*it) no?
Ciao 


No, non è per forza un puntatore ad un elemento.
Quello che succede è che è definito in std::vectory<T>::iterator:
bool operator== (const std::vector<T>::iterator& it) const;
e quindi:
itr1 == itr2
è:
itr1.operator== (itr2);
Se anche:
it == &(*it);
è per una particolare implementazione e non è detto funzioni sempre,
giacché a sinistra avresti:
bool std::vector<T>::iterator::operator== (const
std::vector<T>::iterator&) const;
ma il parametro attuale sarebbe dato da &(*it), e cioè dall'indirizzo
del valore di ritorno di (*it):
T& it.operator* ();
cioé (T*) che è diverso da const (std::vector<T>::iterator&).
Se poi c'è qualche conversione automatica con le STL che usi tu, o
qualche altro operatore definito (come quello di conversione implicita
a booleano), è peculiare della implementazione.
Ciao,
Matteo