2017-01-14 8 views
0

を再宣言することはできません、私は私自身の「スマートイテレータ」を作成しようとしていますし、私はイテレータのタグに応じて、いくつかの演算子を持っているSFINAEを使用したい:SFINAE:クラスメンバーが

ここでは私のコードです:

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); 
} 

とラインRangeFilterIterator &operator+(std::size_t n) = delete

私はエラーを得た: class member cannot be redeclared

私はテンプレートで「良い」とは言えませんが、私はSFINAEでは2つのうちの1つだけが「宣言される」と考えました。何か不足していますか?それ以外のことは可能ですか?

+0

私はclass tag = Tagを使用し、「役に立たない関数」を使用して修正を得ました。しかし、私は関数に "同じ名前"を使用すると、同じエラーが発生します... –

答えて

3

私はテンプレートパラメータの代わりに戻り値の型パラメータを使用しています。

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;