2014-06-28 156 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