2017-01-14 7 views
0
neu deklariert werden

Ich versuche, meinen eigenen „smart Iterator“ zu schaffen, und ich möchte SFINAE verwenden, um einige Betreiber haben auf dem Tag des Iterators abhängig:SFINAE: Klasse Mitglied kann nicht

Hier ist mein Code:

template<class Iterator, class Predicat, class Tag> 
class RangeFilterIterator { 
public: 
    RangeFilterIterator(Iterator begin, Iterator end, Predicat predicat) : 
     mBegin(begin), mEnd(end), mPredicat(predicat) {} 

    bool operator !=(RangeFilterIterator const &r) { 
     return mBegin != r.mBegin; 
    } 

    typename Iterator::value_type &operator*() {return *mBegin;} 

    RangeFilterIterator &operator++() { 
     while(mBegin != mEnd && mPredicat(*mBegin++)); 
     return *this; 
    } 

    template<class = std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, Tag>::value>> 
    RangeFilterIterator &operator+(std::size_t n) { 
     while(n--) 
      ++(*this); 
     return *this; 
    } 

    template<class = std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, Tag>::value>> 
    RangeFilterIterator &operator+(std::size_t n) = delete; 

private: 
    Iterator mBegin, mEnd; 
    Predicat mPredicat; 
}; 

template<typename Container, typename Predicate> 
auto RangeFilter(Container const &c, Predicate p) { 
    using Iterator = RangeFilterIterator<typename Container::iterator, 
             Predicate, 
             typename Container::iterator::iterator_category>; 
    Iterator begin(const_cast<Container&>(c).begin(), const_cast<Container&>(c).end(), p); 
    Iterator end(const_cast<Container&>(c).end(), const_cast<Container&>(c).end(), p); 
    return Range(begin, end); 
} 

und an der Linie RangeFilterIterator &operator+(std::size_t n) = delete habe ich den Fehler: class member cannot be redeclared.

Ich bin nicht "gut" mit Vorlage, aber ich dachte, dass mit SFINAE nur einer der beiden "deklariert" wird. Fehle ich etwas? Es ist möglich, etwas anderes zu tun?

+0

Ich bekomme eine Korrektur mit Klassen-Tag = Tag und mit "nutzlose Funktion". Aber ich habe immer noch den gleichen Fehler, wenn ich den "gleichen Namen" für die Funktion verwende ... –

Antwort

3

Okay, wenn ich Rückgabetyp Parameter anstelle von Vorlagenparameter verwenden, funktioniert es.

template<class tag = Tag> 
std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> 
&operator+(std::size_t n) { 
    while(n--) 
     ++(*this); 
    return *this; 
} 

template<class tag = Tag> 
std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> 
&operator+(std::size_t n) = delete; 
Verwandte Themen