2D Matrix und Funktionsobjekt - Operator[]
-
hi
Ich hab eine etwas seltsame Fehlermeldung
error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const Matrix2D' (or there is no acceptable conversion)
could be 'int *Simple2DimArr::operator [](int)'
while trying to match the argument list '(const Matrix2D, int)'bei folgendem Code. (Die Simple2DimArr Klasse hab ich aus der FAQ)
class Simple2DimArr { private: int* pArr; int Rows, Cols; public: Simple2DimArr(int Zeilen, int Spalten) { Rows = Zeilen; Cols = Spalten; pArr = new int[Rows * Cols]; } int* operator[](int Zeile) { return & pArr[Zeile * Cols]; } ~Simple2DimArr() { delete [] pArr; } }; typedef Simple2DimArr Matrix2D; struct distance_compare { int source_; const Matrix2D& distance_; distance_compare( int source, const Matrix2D& distance ) : source_( source ), distance_( distance ){} bool operator()( const int& lhs, const int& rhs ) { return distance_[source][lhs] > distance_[source][rhs]; // <--- In diese Zeile springt der Debugger } }; //Anwendung int main() { { // Testblock Matrix2D distance(3,3); distance[0][0] = 0; distance[0][1] = 1; distance[0][2] = 2; distance[1][0] = 1; distance[1][1] = 0; distance[1][2] = 1; distance[2][0] = 2; distance[2][1] = 1; distance[2][2] = 0; std::cout << distance[1][1] << std::endl; } return 0; } // getestetes Minimalbsp.Wenn ich die struct distance_compare auskommentiere gehts.
Hat jemand vielleicht einen Tipp für mich?
Wäre super
-
Edit:
..in Zeile 33 sollte es natürlich heissenreturn distance_[source_][lhs] > distance_[source_][rhs];
-
Hab das Problem eingeengt.
Wenn ich beim Member von distance_compareconst Matrix2D& distance_;das const und die Referenz (&) weglasse, kompiliert er obiges Beispiel ohne Murren und gibt 0 aus.
Das Problem ist halt, das ich distance_compare in STL Algorithmen als Vergleichsoperator brauche.
Und dabei gibts ein Assert von "_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)", schätze mal, dass der Array der 2DMatrix (int Zeiger) beim kopieren in den Algorithmus flöten geht.
Wie kann ich dem entgegenwirken?ps: code mit dem ich das getestet habe
int source = 1; distance_compare comp_1( source, distance ); std::priority_queue< int, std::vector<int>, distance_compare > pqueue_1( comp_1 ); for( int i = 0; i < 3; ++i ) { pqueue_1.push( distance[source][i] ); } std::cout << pqueue_1.top() << std::endl; pqueue_1.pop(); std::cout << pqueue_1.top() << std::endl; pqueue_1.pop(); std::cout << pqueue_1.top() << std::endl; pqueue_1.pop();
-
deine struct distance_compare hat ein member const Matrix2D
dadurch kannst du nur Funktionen aufrufen, die auch als const deklariert sind bei deiner klasse.
also noch dazuügen:// in die Klasse const int* const operator[](int Zeile) { return ....} const;
-
Hm, dann kann ich aber nicht mehr die Werte zuweisen.
Lass ich das erste const weg, geht zwar die Zuweisung, aber beim Vergleichen kommt ein Fehler:Unhandled exception at 0x00417861 in Test.exe: 0xC0000005: Access violation reading location 0xfbcefb20.
Habe das Gefühl, ich such im leeren Raum..

-
naja, du hast eben eine const-funktion und eine nicht-konst-fuktion. Der compiler nimmt dann die, die er gerade brauch. Lass beide drin, dann müsts doch gehn
-
*freu*
Mir is grad der Knoten aufgegangen
Stichwort: Assignable für Klassen mit Zeigern und Arrays
Hab dem 2D-Array nen ordentlichen Copyconstructor und operator= verpasst, der mir auch den Array Inhalt korrekt kopiert.
@Maxi
Das geht auch nicht, der Assert kommt wieder. Aber trotzdem Danke! Das const und die Referenz vom Member distance_ sind nun nicht mehr nötig, und alle Aktionen sind nun auch in STL Algorithmen verfügbar.Hier nochmal die aktuelle Version:
class Simple2DimArr { private: int* pArr; int Rows, Cols; public: Simple2DimArr(int Zeilen, int Spalten) { Rows = Zeilen; Cols = Spalten; pArr = new int[Rows * Cols]; } Simple2DimArr( const Simple2DimArr& other ) { Rows = other.Rows; Cols = other.Cols; pArr = new int[Rows * Cols]; for( int i = 0; i < Rows * Cols; ++i ) { pArr[i] = other.pArr[i]; } } Simple2DimArr operator=( const Simple2DimArr& other ) { Rows = other.Rows; Cols = other.Cols; pArr = new int[Rows * Cols]; for( int i = 0; i < Rows * Cols; ++i ) { pArr[i] = other.pArr[i]; } return *this; } int* operator[](int Zeile) { return & pArr[Zeile * Cols]; } ~Simple2DimArr() { delete [] pArr; } }; typedef Simple2DimArr Matrix2D; ////compare funktions objekt struct distance_compare { int source_; Matrix2D distance_; distance_compare( int source, const Matrix2D& distance ) : source_( source ), distance_( distance ){} bool operator()( const int& lhs, const int& rhs ) { return distance_[source_][lhs] > distance_[source_][rhs]; } }; int main() { { // Testblock Matrix2D distance(3,3); distance[0][0] = 0; distance[0][1] = 1; distance[0][2] = 2; distance[1][0] = 1; distance[1][1] = 0; distance[1][2] = 1; distance[2][0] = 2; distance[2][1] = 1; distance[2][2] = 0; std::cout << distance[1][1] << std::endl; //Priority Queue int source = 0; distance_compare comp_1( source, distance ); std::priority_queue< int, std::vector<int>, distance_compare > pqueue_1( comp_1 ); for( int i = 0; i < 3; ++i ) { pqueue_1.push( distance[source][i] ); } std::cout << pqueue_1.top() << std::endl; pqueue_1.pop(); std::cout << pqueue_1.top() << std::endl; pqueue_1.pop(); std::cout << pqueue_1.top() << std::endl; pqueue_1.pop(); } // Testblock return 0; }Für Verbesserungsvorschläge wär ich natürlich auch sehr dankbar.

-
vergiss beim operator= nich, noch dedn alten speicher zu deleten