模板运算符重载出错

时间:2012-07-30 15:11:47

标签: c++ templates operator-overloading

我写了一个类,我想为它实现一个迭代器(如下面的代码所示)。我需要重载各种运算符,我遇到了下面提到的错误:

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*>&)’

知道可能导致这种情况的原因吗?

1 个答案:

答案 0 :(得分:1)

  

4在大多数情况下,类型,模板和非类型值都是   用来组成P参与模板参数推导。那是,   它们可用于确定模板参数的值,以及   如此确定的值必须与确定的值一致   别处。然而,在某些情况下,价值却没有   参与类型推导,但改为使用模板的值   在别处推断或明确指定的参数。   如果模板参数仅在非推导的上下文中使用,则为   未明确指定,模板参数推断失败。

     

非推断的上下文是:        - 使用qualified-id。

指定的类型的嵌套名称说明符

你可以通过几种方式避免这种情况。第一种方式 - 使运营商&lt;类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;
}