2014-06-28 122 views
2

我有一个嵌套模板的自定义迭代器模板类(专门为常量/非const迭代器)是这样的:模板迭代器,铛无法推断模板参数

template <typename T> 
struct A 
{ 
    template <typename U> 
    struct AIterator 
    { 
     //... 
    }; 

    typename AIterator<T*> iterator; 
    typename AIterator<const T*> const_iterator; 
}; 

template <typename T> 
bool operator==(const typename A<T>::iterator& lhs, 
       const typename A<T>::iterator& rhs,) 
{ 
    //... 
} 

template <typename T> 
bool operator!=(const typename A<T>::iterator& lhs, 
       const typename A<T>::iterator& rhs,) 
{ 
    //... 
} 

//idem for const_iterator... 

但铛不能推断模板参数:

snake_test.cpp:17:68: error: invalid operands to binary expression ('wavelet::Snake<float>::const_iterator' (aka 'Iterator<const float *>') and 'const_iterator' (aka 'Iterator<const float *>')) 
     for (wavelet::Snake<float>::const_iterator it = snake.begin(); it != snake.end(); it++) 
                     ~~^~~~~~~~~~~~ 
./snake.hpp:150:6: note: candidate template ignored: couldn't infer template argument 'T' 
bool operator!=(const typename Snake<T>::iterator& lhs, 
    ^
./snake.hpp:164:6: note: candidate template ignored: couldn't infer template argument 'T' 
bool operator!=(const typename Snake<T>::const_iterator& lhs, 
    ^
1 error generated. 

我在做什么错?如何正确实现模板类的自定义迭代器?

+0

其中之一,你的参考标签是在你的论点的错误的一面。例如:'lhs&'应该是'&lhs'等。'rhs'参数后面的逗号也没有帮助。 – WhozCraig

+0

谢谢!我一边写这个问题一边做饭,所以我写得很快,因此可能会有一些错别字。 ;-) – matovitch

+0

您是否试过在'A'里面定义'operator =='和'operator!='? –

回答

4

可能为最简单和最干净的解决方案是使用类体内部限定非成员的朋友的功能:

template <typename T> 
struct A 
{ 
    template <typename U> 
    struct AIterator 
    { 
     friend bool operator==(AIterator const& lhs, AIterator const& rhs) 
     { /* implement here */ } 
    }; 

    typename AIterator<T*> iterator; 
    typename AIterator<const T*> const_iterator; 
}; 

这会创建一个非成员函数为AIterator每个专业化。据我所知,你不能为这个非成员函数提供外部定义 - 它不是函数模板,而是每个专业化的适当函数。所以你只能在全局命名空间中定义一组固定的特化。

+0

我不完全确定为什么嵌套类型处于非推导的上下文中。乍一看,这种类型的信息似乎没有将其与周围范围联系起来;这可能与typedef有关,这是透明的。我不明白为什么关联周围范围的信息是不可能的,但推断它可能会导致一些微妙的问题。 – dyp

+0

谢谢!我也在想朋友。 :-) – matovitch

+0

[这个其他答案](http://stackoverflow.com/questions/12566228/candidate-template-ignored-because-template-argument-could-not-be-inferred)是非常有帮助的!:基本上没有从一个类型到它的封闭类型是一对一的对应关系,所以并不总能保证封闭类型是可以被扣除的。 – NHDaly