che il codice viene compilato a tutti è probabilmente perché avete un using namespace std
da qualche parte. (Altrimenti) That's something I would advise against e hai appena fornito una buona causa perché:
Per errore, la tua chiamata riprende std::distance()
, che accetta due iteratori e calcola la distanza tra loro. Rimuovi la direttiva using e prefissa tutti i tipi di libreria standard con std::
e il compilatore ti dirà che hai provato a passare uno vector <point>::iterator
dove era richiesto un point*
.
Per ottenere un puntatore a un oggetto a cui punta un iteratore, è necessario effettuare il dereferenziamento dell'iteratore, che fornisce un riferimento all'oggetto, e prendere l'indirizzo del risultato: &*ii
.
(Si noti che un puntatore soddisfa perfettamente tutti i requisiti per un iteratore std::vector
e alcune implementazioni precedenti della libreria standard infatti utilizzavano puntatori per questo, che permettevano di trattare gli iteratori std::vector
come puntatori, ma le moderne implementazioni usano una classe di iteratore speciale per quello . suppongo che il motivo è che l'utilizzo di una classe permette funzioni per i puntatori e gli iteratori sovraccarico. Inoltre, utilizzando i puntatori come std::vector
iteratori incoraggia la miscelazione puntatori e iteratori, che impediranno il codice per compilare quando si cambia il vostro contenitore.)
Ma piuttosto che farlo, ti suggerisco di cambiare la tua funzione in modo che richieda riferimenti (vedi this answer perché è comunque una buona idea.):
float distance(const point& p1, const point& p2)
{
return sqrt((p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y));
}
Si noti che i punti sono presi dai riferimenti const
. Questo indica al chiamante che la funzione non cambierà i punti che è passato.
Quindi è possibile chiamarlo in questo modo: distance(*ii,*jj)
.
Una nota a parte, questo
typedef struct point {
float x;
float y;
} point;
è un C-ism non necessarie in C++. Basta scriverlo
struct point {
float x;
float y;
};
che farebbe problemi se questa definizione struct
mai stato quello di analizzare da un compilatore C (il codice avrebbe dovuto fare riferimento a struct point
poi, non semplicemente point
), ma credo che std::vector
e simili sarebbe essere molto più di una sfida per un compilatore C comunque.
Questa risposta è errata. std :: distance può essere raccolto da ADL su un std :: iterator, quindi può far parte del set candidato indipendentemente dal fatto che sia o meno usato 'std'. – Puppy
@Puppy: Questo è vero (e per 2,5 anni nessuno se n'è accorto), ma non è tutta la mia risposta. Passare punti per 'const point & p1' risolverà anche questo problema. – sbi
@sbi: No, non risolverà il problema. Sarà ancora possibile scrivere erroneamente 'distance (ii, jj)' e ottenere 'std :: distance'. –