2012-07-30 80 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