2016-07-25 16 views
2

Mein Ziel ist es zu lernen, einen benutzerdefinierten Iterator von Grund auf neu zu schreiben.Implementieren benutzerdefinierter Iterator für die Arbeit mit Std :: Sort

#include <iterator> 

template<class D> 
class SpanIterator final : public std::iterator<std::random_access_iterator_tag, D> 
{ 
private: 
    D* _data; 

public: 
    explicit SpanIterator(D* data) : 
     _data{ data } 
    { 
    } 

    SpanIterator(const SpanIterator& itertator) = default; 

    SpanIterator& operator=(const SpanIterator& iterator) = default; 

    SpanIterator& operator=(D* data) 
    { 
     _data = data; 

     return *this; 
    } 

    operator bool() const 
    { 
     return _data != nullptr; 
    } 

    bool operator==(const SpanIterator& itertator) const 
    { 
     return _data == itertator._data; 
    } 

    bool operator!=(const SpanIterator& itertator) const 
    { 
     return _data != itertator._data; 
    } 

    SpanIterator& operator+=(const std::ptrdiff_t& movement) 
    { 
     _data += movement; 

     return *this; 
    } 

    SpanIterator& operator-=(const std::ptrdiff_t& movement) 
    { 
     _data -= movement; 

     return *this; 
    } 

    SpanIterator& operator++() 
    { 
     ++_data; 

     return *this; 
    } 

    SpanIterator& operator--() 
    { 
     --_data; 

     return *this; 
    } 

    SpanIterator operator++(int) 
    { 
     auto temp = *this; 

     ++_data; 

     return temp; 
    } 

    SpanIterator operator--(int) 
    { 
     auto temp = *this; 

     --_data; 

     return temp; 
    } 

    SpanIterator operator+(const std::ptrdiff_t& movement) 
    { 
     auto oldPtr = _data; 

     _data += movement; 

     auto temp = *this; 

     _data = oldPtr; 

     return temp; 
    } 

    SpanIterator operator-(const std::ptrdiff_t& movement) 
    { 
     auto oldPtr = _data; 

     _data -= movement; 

     auto temp = *this; 

     _data = oldPtr; 

     return temp; 
    } 

    D& operator*() 
    { 
     return *_data; 
    } 

    const D& operator*() const 
    { 
     return *_data; 
    } 

    D& operator->() 
    { 
     return _data; 
    } 
}; 

Was ich testen bin wie so: Ich habe die folgende Iterator geschrieben

#include <iostream> 
#include <array> 

int main() 
{ 
    std::array<double, 3> values = { 1, 2, 1 }; 

    SpanIterator<double> begin{ values.data() }; 
    SpanIterator<double> end{ values.data() + values.size() }; 

    std::sort(begin, end); 

    return EXIT_SUCCESS; 
} 

jedoch, es zu kompilieren fehlschlägt, geben die folgenden Fehler:

  • Fehler C2666 ‚SpanIterator: : operator - ': 2 Überladungen
  • Fehler C2780' void std :: _ Sort_unchecked1 (_RanIt, _RanIt, _Diff, _Pr &) ': 4 Argumente erwartet - 3
  • bereitgestellt

Wenn ich SpanIterator operator-(const std::ptrdiff_t& movement) entferne ich verschiedene Fehlermeldungen erhalten:

  • 'Leer std :: _ Guess_median_unchecked (_RanIt, _RanIt, _RanIt, _Pr &)': kann nicht ableiten Vorlage Argument für '_RanIt' von 'int'
  • '_Guess_median_unchecked': keine passende überladene Funktion gefunden
  • Fehler C2100 illegal indirection

Antwort

4

Sie Betreiber zu unterstützen, die following operations (wo a und b sind Werte Ihrer Iteratortyp SpanIterator<...>) fehlt:

  • b - a
  • a < b (und die übrigen Vergleiche, obwohl die meisten Implementierungen von std::sort don‘ t verwende sie).

Zum Beispiel könnten Sie die folgenden Member Betreiber Überlastungen bieten:

std::ptrdiff_t operator-(SpanIterator const&) const; 
bool operator<(SpanIterator const&) const; 
// etc. 

(Beachten Sie, dass Dritt Überlastungen bevorzugt werden häufig: Operator overloading)

Zusätzlich Ihre operator boolexplicit sein sollte um mehrdeutige Überlastungen für die Operationen a + n, n + a und b - a zu vermeiden (wobei n ein Wert Ihres Differenztyps ist, dh std::ptrdiff_t).

+0

Das explizite Hinzufügen zu 'operator bool' und das Hinzufügen der beiden Operatoren, die du erwähnt hast, haben den Trick geschafft - danke schön :-) – keith

Verwandte Themen