Print 2 D Vektor to ostream
-
Hallo,
es gibt zwar etliche Treffer bei der Suche zu diesem Thema aber ich kapiers nicht.
Ich habe einen 2D Vektor vom Typ meiner Struktur und möchte diese durch Überladen des ostream Operators ausgeben. Ich deklariere doch meinen stream operator im namespace std, warum wird der Operator nicht erkannt?Folgende Fehlermeldung:
Multiple markers at this line
- candidates are:
- no match for 'operator!=' in 'itAdj != (& a)->std::vector<_Tp, _Alloc>::end [with _Tp =
std::vector<std::vector<Edge> >, _Alloc = std::allocator<std::vector<std::vector<Edge> > >, std::vector<_Tp,
_Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::vector<std::vector<Edge> >,
std::vector<std::vector<std::vector<Edge> > > >, typename std::_Vector_base<_Tp,
_Alloc>::_Tp_alloc_type::const_pointer = const std::vector<std::vector<Edge> >]()'
- candidate is:
- no match for 'operator=' in 'itAdj = (& a)->std::vector<_Tp, _Alloc>::begin [with _Tp =
std::vector<std::vector<Edge> >, _Alloc = std::allocator<std::vector<std::vector<Edge> > >, std::vector<_Tp,
_Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const std::vector<std::vector<Edge> >,
std::vector<std::vector<std::vector<Edge> > > >, typename std::_Vector_base<_Tp,
_Alloc>::_Tp_alloc_type::const_pointer = const std::vector<std::vector<Edge> >]()'#include <iostream> #include <vector> using namespace std ; //Eine Kante hat einen Zielknoten n und eine lfd nr struct Edge { int n; int nr; Edge(int n_, int nr_) { n = n_ ; nr = nr_ ; } }; //Alias fuer Graph typedef vector <vector <Edge > > AdjList; std::ostream& operator << (std::ostream &o, const std::vector<AdjList> &a) { using namespace std; vector<int>::iterator itV; vector< vector<int> >::iterator itAdj; for ( itAdj=a.begin(); itAdj!=a.end(); itAdj++ ) -------------->hier { for (itV = itAdj->begin(); itV != itAdj->end(); itV++) { //cout << " " << *itV; o << "innen: " << *itV << std::endl; } } return o; } int main() { //n Anzahl Knoten, m Anzahl der Kanten des Graphen int n , m ; n=8; AdjList graph(n); //Kante von Knoten zu Knoten mit lfdNr graph[1].push_back(Edge(2,0)); graph[1].push_back(Edge(5,0)); graph[2].push_back(Edge(4,0)); graph[2].push_back(Edge(3,0)); graph[2].push_back(Edge(1,0)); graph[3].push_back(Edge(2,0)); graph[3].push_back(Edge(4,0)); graph[4].push_back(Edge(5,0)); graph[4].push_back(Edge(3,0)); graph[4].push_back(Edge(2,0)); graph[5].push_back(Edge(1,0)); graph[5].push_back(Edge(4,0)); return 0; }vielen DAnk
-
itAdjist einvector< vector<int> >::iterator.aist eine Referenz aufvector<vector<vector<Edge> > >. Wie solla.begin()initAdjpassen können?Das ist übrigens was generell faul mit deinem Design. Man schreibt normalerweise keine Ausgabeoperatoren für
vector<X>. Man schreibt einen für X und macht dann etwas wiefor(X x: mein_vector) out << x;oder vergleichbares. Hier ist X die AdjList.
Außerdem ist:
Ich deklariere doch meinen stream operator im namespace std
schlichtweg falsch. Tust du nicht. Solltest du hier auch nicht.
-
Das ist kein 2D Vector sondern ein 3D Vector.
Du hast das typedef auf vector< vector<edge> > und dann nimmst du in der operatorenüberladung noch davon einen vector an -> vector< vector< vector<edge> > > = 3D
Du iterierst aber nur mit 2 Schleifen drüber, d.h. das Ergebnis davon ist ein Vector<edge> und nicht deine edge.Aber der Code und die Fehlermeldungen stimmen nicht ganz, zeig mal den Kompletten Code (wenigstens die relevanten Definitionen)
-
Danke.
Ja klar, ich hatte einen 3d Vektor. Brauche aber nur 2D.
Habe jetzt die Deklaration vom Vektor geändert.
Mein Ziel ist es, das was ich dem graph in der main Methode hinzugefügt habe, auszugeben.AdjList graph(n); //Kante von Knoten a zu Knoten b mit lfdNr c graph[1].push_back(Edge(2,0)); //hierzu benötige ich die Ausgabehier der gesamte code:
//============================================================================ // Name : Adjazenzliste.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <vector> using namespace std ; //Eine Kante hat einen Zielknoten n und eine lfd nr struct Edge { int n; int nr; Edge(int n_, int nr_) { n = n_ ; nr = nr_ ; } }; //Alias fuer Graph typedef vector <vector <Edge > > AdjList; std::ostream& operator << (std::ostream &o, const AdjList &a) { using namespace std; vector<int>::iterator itV; vector< vector<Edge> >::iterator itAdj; for ( itAdj=a.begin(); itAdj!=a.end(); itAdj++ ) //-------------->hier { for (itV = itAdj->begin(); itV != itAdj->end(); itV++) { //cout << " " << *itV; o << "innen: " << *itV << std::endl; } } return o; } int main() { //n Anzahl Knoten, m Anzahl der Kanten des Graphen int n; n=8; AdjList graph(n); //Kante von Knoten a zu Knoten b mit lfdNr c graph[1].push_back(Edge(2,0)); graph[1].push_back(Edge(5,0)); graph[2].push_back(Edge(4,0)); graph[2].push_back(Edge(3,0)); graph[2].push_back(Edge(1,0)); graph[3].push_back(Edge(2,0)); graph[3].push_back(Edge(4,0)); graph[4].push_back(Edge(5,0)); graph[4].push_back(Edge(3,0)); graph[4].push_back(Edge(2,0)); graph[5].push_back(Edge(1,0)); graph[5].push_back(Edge(4,0)); return 0; }
-
Zweimal selber nachdedacht und Dir wäre aufgefallen, dass einer der Iteratoren einen Typ hat, der überhaupt keinen Sinn ergibt (Überbleibsel einer früheren Version?)
Desweiteren arbeitest Du mit einer Referenz auf const AdjList, dann solltest Du auch const_iterator nehmen.
std::ostream& operator << (std::ostream &o, const AdjList &a) { typedef AdjList::const_iterator VIter; typedef AdjList::value_type::const_iterator EIter; for (VIter itAdj=a.begin(); itAdj!=a.end(); itAdj++ ) //-------------->hier { for (EIter itV = itAdj->begin(); itV != itAdj->end(); itV++) { //cout << " " << *itV; o << "innen: " << *itV << std::endl; } } return o; }Dir fehlt noch der Ausgabeoperator für Edge.
-
Grad bei solchen Iterationen über komplexe Datenstrukturen, die eventuell noch nicht final sind hilft ne foreach Schleife:
for(auto x : vec) // oder auto & x for(auto y : x) // oder auto & y cout << y << endl;
-
Danke!
Mit code von furblewurble + Ausgabeoperator für Edge:
std::ostream& operator << (std::ostream &o, const Edge &a) { o << "Knoten: " << a.n << " LfdNr: " << a.nr << std::endl; return o; }gehts jetzt.