Random Access Iterator [solved]
-
Ich hab für meine Matrix-Klasse einen RandomAccessIterator geschreiben: Beim Kompilieren bekomme ich aber Fehler (wenn ich z.B. std::sort aufrufe). Was hab ich falsch gemacht? Lasse ich den sort-Aufruf weg, kompiliert mein Programm.
Hier sind jeweils Ausschnitte aus meinem Code. Ich hoffe ihr könnt den Fehler finden.
LinearAlgebra.cpp
int main() { Matrix<int> m = useful::randomIntMatrix(4,4, -100, 100); sort(m.begin(), m.end()); cout << m; }matrix.h
template<class T> class Matrix { public: class matrix_iterator; friend class matrix_iterator; class matrix_iterator : public std::iterator<std::random_access_iterator_tag, T> { Matrix<T> *m; int i, j; public: typedef std::random_access_iterator_tag it_cat; typedef typename std::iterator<it_cat, T>::value_type value_type; typedef typename std::iterator<it_cat, T>::difference_type diff_type; typedef typename std::iterator<it_cat, T>::reference reference; typedef typename std::iterator<it_cat, T>::pointer pointer; matrix_iterator(Matrix<T>& mat, bool end = false); matrix_iterator(); matrix_iterator(const matrix_iterator&); matrix_iterator& operator=(const matrix_iterator&); matrix_iterator& operator++(); matrix_iterator& operator--(); matrix_iterator operator++(int); matrix_iterator operator--(int); matrix_iterator& operator+=(diff_type); matrix_iterator& operator-=(diff_type); matrix_iterator operator+(diff_type) const; matrix_iterator operator-(diff_type) const; matrix_iterator operator+(const matrix_iterator&) const; matrix_iterator operator-(const matrix_iterator&) const; reference operator*() const; pointer operator->() const; reference operator[](diff_type) const; bool operator==(const matrix_iterator& it) const; bool operator!=(const matrix_iterator& it) const; bool operator<(const matrix_iterator& it) const; bool operator>(const matrix_iterator& it) const; bool operator<=(const matrix_iterator& it) const; bool operator>=(const matrix_iterator& it) const; }; matrix_iterator begin(); matrix_iterator end();Falls auch die Implementierungen relevant sind:
template <class T> Matrix<T>::matrix_iterator::matrix_iterator(Matrix<T>& mat, bool end) { m = &mat; if (end) { i = mat.dim1_; j = 0; } else { i = 0; j = 0; } } template <class T> Matrix<T>::matrix_iterator::matrix_iterator() { m = NULL; i = 0; j = 0; } template <class T> Matrix<T>::matrix_iterator::matrix_iterator(const matrix_iterator& it) { m = it.m; i = it.i; j = it.j; } template <class T> typename Matrix<T>::matrix_iterator& Matrix<T>::matrix_iterator::operator=(const matrix_iterator& it) { m = it.m; i = it.i; j = it.j; return *this; } template <class T> typename Matrix<T>::matrix_iterator& Matrix<T>::matrix_iterator::operator++() { j++; if (j >= m->dim2_) { j = 0; i++; } return *this; } template <class T> typename Matrix<T>::matrix_iterator& Matrix<T>::matrix_iterator::operator--() { j--; if (j < 0) { j = m->dim2_ - 1; i--; } return *this; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator++(int) { matrix_iterator it(*this); j++; if (j >= m->dim2_) { j = 0; i++; } return it; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator--(int) { matrix_iterator it(*this); j--; if (j < 0) { j = m->dim2_ - 1; i--; } return it; } template <class T> typename Matrix<T>::matrix_iterator& Matrix<T>::matrix_iterator::operator+=(diff_type x) { int d = m->dim2_; long long t = i * d + j + x; i = t / d; j = t % d; return *this; } template <class T> typename Matrix<T>::matrix_iterator& Matrix<T>::matrix_iterator::operator-=(diff_type x) { int d = m->dim2_; long long t = i * d + j - x; i = t / d; j = t % d; return *this; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator+(diff_type x) const { matrix_iterator it; it.m = m; int d = m->dim2_; long long t = i * d + j + x; it.i = t / d; it.j = t % d; return it; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator-(diff_type x) const { matrix_iterator it; it.m = m; int d = m->dim2_; long long t = i * d + j - x; it.i = t / d; it.j = t % d; return it; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator+(const matrix_iterator& it) const { matrix_iterator erg; erg.m = m; int d = m->dim2_; long long t = i * d + j + it.i * it.m->dim2_ + it.j; erg.i = t / d; erg.j = t % d; return erg; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::matrix_iterator::operator-(const matrix_iterator& it) const { matrix_iterator erg; erg.m = m; int d = m->dim2_; long long t = i * d + j - it.i * it.m->dim2_ - it.j; erg.i = t / d; erg.j = t % d; return erg; } template <class T> typename Matrix<T>::matrix_iterator::reference Matrix<T>::matrix_iterator::operator*() const { return (*m)(i,j); } template <class T> typename Matrix<T>::matrix_iterator::pointer Matrix<T>::matrix_iterator::operator->() const { return &((*m)(i,j)); } template <class T> typename Matrix<T>::matrix_iterator::reference Matrix<T>::matrix_iterator::operator[](diff_type x) const { return (*m)[x]; } template <class T> bool Matrix<T>::matrix_iterator::operator==(const matrix_iterator& it) const { return i == it.i && j == it.j; } template <class T> bool Matrix<T>::matrix_iterator::operator!=(const matrix_iterator& it) const { return i != it.i || j != it.j; } template <class T> bool Matrix<T>::matrix_iterator::operator<(const matrix_iterator& it) const { if (i == it.i) return j < it.j; else return i < it.i; } template <class T> bool Matrix<T>::matrix_iterator::operator>(const matrix_iterator& it) const { if (i == it.i) return j > it.j; else return i > it.i; } template <class T> bool Matrix<T>::matrix_iterator::operator<=(const matrix_iterator& it) const { if (i == it.i) return j <= it.j; else return i <= it.i; } template <class T> bool Matrix<T>::matrix_iterator::operator>=(const matrix_iterator& it) const { if (i == it.i) return j >= it.j; else return i >= it.i; } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::begin() { return matrix_iterator(*this); } template <class T> typename Matrix<T>::matrix_iterator Matrix<T>::end() { return matrix_iterator(*this, true); }Hier die ersten Zeilen der Ausgabe des Compilers...
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/algorithm:63:0, from ..\src\../include/cpplapack.h:18, from ..\src\matrix.h:18, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h: In Instanziierung von »void std::sort(_RAIter, _RAIter) [with _RAIter = std::iterator<std::random_access_iterator_tag, int>]«: ..\src\LinearAlgebra.cpp:197:14: von hier erfordert c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Fehler: keine Übereinstimmung für »operator!=« in »__first != __last« c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Anmerkung: Kandidaten sind: In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/iosfwd:42:0, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/ios:39, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/istream:40, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/fstream:40, from ..\src\Useful.h:16, from ..\src\BayRegFunc.h:75, from ..\src\matrix.h:14, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/postypes.h:223:5: Anmerkung: template<class _StateT> bool std::operator!=(const std::fpos<_StateT>&, const std::fpos<_StateT>&) c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/postypes.h:223:5: Anmerkung: Herleitung/Ersetzung von Templateargument gescheitert: In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/algorithm:63:0, from ..\src\../include/cpplapack.h:18, from ..\src\matrix.h:18, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Anmerkung: »std::iterator<std::random_access_iterator_tag, int>« ist nicht vom Typ »const std::fpos<_StateT>« abgeleitet In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algobase.h:65:0, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/char_traits.h:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/ios:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/istream:40, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/fstream:40, from ..\src\Useful.h:16, from ..\src\BayRegFunc.h:75, from ..\src\matrix.h:14, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_pair.h:225:5: Anmerkung: template<class _T1, class _T2> constexpr bool std::operator!=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_pair.h:225:5: Anmerkung: Herleitung/Ersetzung von Templateargument gescheitert: In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/algorithm:63:0, from ..\src\../include/cpplapack.h:18, from ..\src\matrix.h:18, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Anmerkung: »std::iterator<std::random_access_iterator_tag, int>« ist nicht vom Typ »const std::pair<_T1, _T2>« abgeleitet In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algobase.h:68:0, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/char_traits.h:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/ios:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/istream:40, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/fstream:40, from ..\src\Useful.h:16, from ..\src\BayRegFunc.h:75, from ..\src\matrix.h:14, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_iterator.h:305:5: Anmerkung: template<class _Iterator> bool std::operator!=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&) c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_iterator.h:305:5: Anmerkung: Herleitung/Ersetzung von Templateargument gescheitert: In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/algorithm:63:0, from ..\src\../include/cpplapack.h:18, from ..\src\matrix.h:18, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Anmerkung: »std::iterator<std::random_access_iterator_tag, int>« ist nicht vom Typ »const std::reverse_iterator<_Iterator>« abgeleitet In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algobase.h:68:0, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/char_traits.h:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/ios:41, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/istream:40, from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/fstream:40, from ..\src\Useful.h:16, from ..\src\BayRegFunc.h:75, from ..\src\matrix.h:14, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_iterator.h:355:5: Anmerkung: template<class _IteratorL, class _IteratorR> bool std::operator!=(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&) c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_iterator.h:355:5: Anmerkung: Herleitung/Ersetzung von Templateargument gescheitert: In file included from c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/algorithm:63:0, from ..\src\../include/cpplapack.h:18, from ..\src\matrix.h:18, from ..\src\RandomMatrix.h:14, from ..\src\BCH.h:11, from ..\src\LinearAlgebra.cpp:6: c:\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/stl_algo.h:5431:7: Anmerkung: »std::iterator<std::random_access_iterator_tag, int>« ist nicht vom Typ »const std::reverse_iterator<_IteratorL>« abgeleitet(es ist in Wirklichkeit noch deutlich mehr)
-
Ich sehe nicht den entsprechenden STL-Header:
#include <algorithm>
-
In Instanziierung von »void std::sort(_RAIter, _RAIter) [with _RAIter = std::iterator<std::random_access_iterator_tag, int>]«:
Das ist unerwartet: deinem Code zufolge sollte der deduzierte Typ Matrix<int>::matrix_iterator sein.
Bist du sicher, das der gepostete Code tatsächlich mit dem fehlerhaften übereinstimmt?
-
algorithm wird inkludiert (auch in der matrix.h, falls das nötig sein sollte).
@Camper:
Ja, den fehlerhaften Code hab ich kopiert und hier gepostet.
-
*push*
-
Ramanujan schrieb:
*push*
Minimalen aber vollständigen (in Hinblick auf den Fehler) Code bitte, damit wir das nachvollziehen können.
-
Ich hab den Fehler nun selbst gefunden:
operator+(const matrix_iterator&) const;
operator-(const matrix_iterator&) const;müssen jeweils diff_type zurückgeben und keinen matrix_iterator. Das Problem ist, dass das erstmal nicht zu einem Fehler führt, sondern erst, wenn im std::sort-Algorithmus auf der Differenz aus begin- und end-Iterator der operator>>= aufgerufen wird. Daher kamen diese recht merkwürdigen Fehler.
Ich hab aber noch eine Frage: Der Rückgabewert von operator- ist klar. Aber bei operator+? Wenn ich das auf Pointer übertrage: Was hat es für einen Sinn, zwei Pointer zu addieren? Da landet man doch irgendwo im Niergendwo im Speicher.
Edit: Ok, von dem operator+ der zwei Iteratoren bekommt steht nichts bei cpp-reference. Da war meine Vorlage für den RandomAccessIterator einfach falsch. (mit dem falschen Rückgabetyp hatte ich aber selbst falsch abgeschrieben)