Dass Ihr Code überhaupt kompiliert wird, liegt wahrscheinlich daran, dass Sie using namespace std
irgendwo einen haben. (Sonst vector
müsste es sein std::vector
.) Davon würde ich abraten, und Sie haben gerade einen guten Fall angeführt, warum:
Ihr Anruf wird versehentlich entgegengenommen std::distance()
, was zwei Iteratoren erfordert und die Entfernung zwischen ihnen berechnet. Entfernen Sie die using-Direktive und stellen Sie allen Standardbibliothekstypen das Präfix voran, std::
und der Compiler teilt Ihnen mit, dass Sie versucht haben, a zu übergeben, vector <point>::iterator
wo a point*
erforderlich war.
Um einen Zeiger auf ein Objekt zu erhalten, auf das ein Iterator zeigt, müssen Sie den Iterator dereferenzieren - der einen Verweis auf das Objekt gibt - und die Adresse des Ergebnisses übernehmen : &*ii
.
(Beachten Sie, dass ein Zeiger alle Anforderungen für einen std::vector
Iterator perfekt erfüllen würde und einige frühere Implementierungen der Standardbibliothek tatsächlich Zeiger dafür verwendeten, wodurch Sie std::vector
Iteratoren als Zeiger behandeln konnten. Moderne Implementierungen verwenden jedoch eine spezielle Iteratorklasse dafür Der Grund dafür ist, dass die Verwendung einer Klasse das Überladen von Funktionen für Zeiger und Iteratoren ermöglicht. Die Verwendung von Zeigern als std::vector
Iteratoren fördert außerdem das Mischen von Zeigern und Iteratoren, wodurch verhindert wird, dass der Code kompiliert wird, wenn Sie Ihren Container ändern.)
Aber anstatt dies zu tun, schlage ich vor, dass Sie Ihre Funktion so ändern, dass stattdessen Referenzen verwendet werden (siehe diese Antwort, warum das sowieso eine gute Idee ist.):
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));
}
Beachten Sie, dass die Punkte von const
Referenzen übernommen werden . Dies zeigt dem Anrufer an, dass die Funktion die übergebenen Punkte nicht ändert.
Dann können Sie es so nennen : distance(*ii,*jj)
.
Nebenbei bemerkt, dies
typedef struct point {
float x;
float y;
} point;
ist ein C-Ismus in C ++ unnötig. Buchstabiere es einfach
struct point {
float x;
float y;
};
Das würde Probleme struct
bereiten , wenn diese Definition jemals von einem C-Compiler analysiert werden sollte (der Code müsste struct point
dann nicht einfach darauf verweisen point
), aber ich denke, std::vector
und dergleichen wäre für einen C-Compiler sowieso eine weitaus größere Herausforderung.
std
.const point& p1
löst auch dieses Problem.distance(ii, jj)
und zu bekommenstd::distance
.::distance(...)
anstatt zu schreiben,distance(...)
wann Sie die Funktion aufrufen. Ihredistance
Funktion ist im globalen Namespace definiert, sodass Sie den Namen Ihrer Funktion mit einem leeren Präfix qualifizieren können::distance
(und natürlich müssen Sie den Iterator dereferenzieren, um ihn ordnungsgemäß aufzurufen).Zufällig verwenden Sie tatsächlich eine integrierte STL-Funktion "distance" , die die Entfernung zwischen Iteratoren berechnet, anstatt Ihre eigene Entfernungsfunktion aufzurufen. Sie müssen Ihre Iteratoren "dereferenzieren", um das enthaltene Objekt zu erhalten.
cout << distance(&(*ii), &(*jj)) << " ";
Wie Sie der obigen Syntax entnehmen können, ähnelt ein "Iterator" einem verallgemeinerten "Zeiger". Der Iterator kann nicht direkt als "Ihr" Objekttyp verwendet werden. Tatsächlich sind Iteratoren Zeigern so ähnlich, dass viele Standardalgorithmen, die mit Iteratoren arbeiten, auch mit Zeigern gut funktionieren.
Wie Sbi bemerkte: Ihre Distanzfunktion nimmt Zeiger. Es wäre besser, stattdessen const-Referenzen zu verwenden, was die Funktion "kanonischer" c ++ machen und die Iterator-Dereferenzierungssyntax weniger schmerzhaft machen würde.
float distance(const point& i_p1, const point& i_p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y)); } cout << distance(*ii, *jj) << " ";
quelle
Sie könnten ein paar Dinge tun:
distance()
Funktion aufpoint
Objekte verweisen . Dies dient nur dazu, die Lesbarkeit derdistance()
Funktion zu verbessern: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)); }
distance()
damit Sie diepoint
Objekte übergeben: Wenn Sie die Schnittstelle derdistance()
Funktion nicht ändern , müssen Sie sie möglicherweise wie folgt aufrufen, um geeignete Zeiger zu erhalten:quelle