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>
    

  • Mod

    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*


  • Mod

    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)


Anmelden zum Antworten