2012-07-30 84 views
-1

我寫了一個類,我想爲它實現一個迭代器(如下面的代碼所示)。我需要重載各種運營商和我面臨下面提到的錯誤:編譯它給了我下面的錯誤模板運算符重載錯誤

class BaseClass 
{ 
    virtual ~BaseClass() {} 
}; 

template<class T> 
class AbstractBaseOrgan: public BaseClass 
{ 
public: 
    typedef T value; 
    template<class TT> 
    class AbstractBaseIterator: 
     public std::iterator<std::random_access_iterator_tag, 
     typename std::iterator_traits<TT>::value_type> 
    { 
    protected: 
     TT _M_current; 
     const TT& 
     base() const 
     { return this->_M_current; } 
    }; 
protected: 
    value te; 
}; 


template<typename Iter> 
inline bool 
operator<(const typename AbstractBaseOrgan<typename 
    std::iterator_traits<Iter>::value_type>::template 
    AbstractBaseIterator<Iter>& lhs, 
    const typename AbstractBaseOrgan<typename 
    std::iterator_traits<Iter>::value_type>::template 
    AbstractBaseIterator<Iter>& rhs) 
{ return lhs.base() < rhs.base(); } 

int main() 
{ 
    AbstractBaseOrgan<int>::AbstractBaseIterator<int*> temp; 
    AbstractBaseOrgan<int>::AbstractBaseIterator<int*> temp2; 
    int ttemp; 
    if(operator< (temp,temp2)) 
     ttemp = 0; 
    return 0; 
} 

error: no matching function for call to ‘operator<(AbstractBaseOrgan<int>::AbstractBaseIterator<int*>&, AbstractBaseOrgan<int>::AbstractBaseIterator<int*>&)’ 

任何想法可能會導致這樣?

+0

它可能不相關的問題,但你不應該使用[保留名稱(http://stackoverflow.com/questions/228783)如'_Iterator'和'__lhs'。 – 2012-07-30 15:27:32

+0

編譯器無法推導出類型。如果(運算符< (temp,temp2))會很好地編譯。 – ForEveR 2012-07-30 15:31:15

+0

可能是相關的:http://stackoverflow.com/questions/8308213/workaround-for-non-deduced-context – user396672 2012-07-30 15:39:26

回答

1

4 In most cases, the types, templates, and non-type values that are used to compose P participate in template argument deduction. That is, they may be used to determine the value of a template argument, and the value so determined must be consistent with the values determined elsewhere. In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

The non-deduced contexts are: — The nested-name-specifier of a type that was specified using a qualified-id.

您可以通過幾種方法避免這種情況。第一種方法 - 使運算符<爲AbstractIteratorBase類的成員或朋友。

template<class TT> 
class AbstractBaseIterator: 
    public std::iterator<std::random_access_iterator_tag, 
    typename std::iterator_traits<TT>::value_type> 
{ 
    public: 
     template<typename Iter> 
     friend bool operator < (const AbstractBaseIterator<Iter>& lhs, const AbstractBaseIterator<Iter>& rhs) 
     { 
      return lhs.base() < rhs.base(); 
     } 
protected: 
    TT _M_current; 
    const TT& 
    base() const 
    { return this->_M_current; } 
}; 

第二個變體是在模板類定義AbstractBaseIterator類沒有。然後在AbstractBaseOrgan中使用typedef AbstractBaseIterator<T> iterator;。如果你可以使用C++ 11,你可以使用這樣的東西。

class BaseClass 
{ 
    virtual ~BaseClass() {} 
}; 

template<class TT> 
class AbstractBaseIterator: 
public std::iterator<std::random_access_iterator_tag, 
typename std::iterator_traits<TT>::value_type> 
{ 
protected: 
    TT _M_current; 
    const TT& 
    base() const 
    { return this->_M_current; } 
}; 

template<typename Iter> 
bool operator < (const AbstractBaseIterator<Iter>& lhs, const AbstractBaseIterator<Iter>& rhs) 
{ 
    return lhs.base() < rhs.base(); 
} 

template<class T> 
class AbstractBaseOrgan: public BaseClass 
{ 
public: 
    typedef T value; 
    template<typename TT> 
    using iterator = AbstractBaseIterator<TT>; 
protected: 
    value te; 
}; 

int main() 
{ 
    AbstractBaseOrgan<int>::iterator<int*> temp; 
    AbstractBaseOrgan<int>::iterator<int*> temp2; 
    int ttemp; 
    if(operator< (temp,temp2)) 
     ttemp = 0; 
    return 0; 
} 
+0

可以遇到的一個更醜陋的場景。 – pmr 2012-07-30 16:00:20

+0

爲什麼這是醜陋的? – 2012-07-30 17:15:48

+0

@ user1539100我重寫我的答案。首先評論另一個答案。 – ForEveR 2012-07-30 17:17:59