2016-12-07 2 views
1

Я конвертирую две существующие функции, которые проверяют, является ли итератор последним и вторым последним элементом в шаблонах std::map. Компиляция шаблона isLastItem, ошибка isSecondLastItem с сообщением об ошибке, которого я не понимаю.Шаблон для 2-го последнего в коллекции; reverse_iterator не компилирует

Одна строка вызывает ошибку является typename T::reverse_iterator secondLastIt = collection.rbegin();

Но шаблон и версии без шаблонов выглядят одинаково.

typedef std::map<time_t, std::string> TInfoMap; 

class MainClass 
{ 
public: 
    MainClass() {}; 
    void test(); 

private: 
    /* Doesn't work */ 
    template <typename T> 
    bool 
    isSecondLastTemplate(const T &collection, const typename T::const_iterator &searchItem) 
    { 
     typename T::reverse_iterator secondLastIt = collection.rbegin(); 
     return true; 
    } 

    /* this works */ 
    bool 
    isSecondLastNoTemplate(const TInfoMap &infoMap, const TInfoMap::const_iterator &searchItem) 
    { 
     TInfoMap::reverse_iterator secondLastIt = infoMap.rbegin(); 
     return true; 
    } 

    /* This works */ 
    template <typename T> 
    bool 
    isLastItem(const T &collection, const typename T::const_iterator &searchItem) 
    { 
     if (collection.size() == 1) 
      return true; 

     // point to last item 
     typename T::const_iterator lastItem = collection.end(); 
     --lastItem; 

     return searchItem == lastItem; 
    } 

private: 
    TInfoMap mInfoMap; 
}; 


void 
MainClass::test() 
{ 
    mInfoMap[1] = "One"; 
    mInfoMap[2] = "Two"; 
    mInfoMap[3] = "Three"; 

    TInfoMap::iterator it = mInfoMap.begin(); 

    if (isLastItem(mInfoMap, it)) 
     printf("Last Item!\n"); 

    if (isSecondLastTemplate(mInfoMap, it)) 
     printf("Second Last!\n"); 

    if (isSecondLastNoTemplate(mInfoMap, it)) 
     printf("Second Last!\n"); 

} 

int 
main(int argc, char **argv) 
{ 
    MainClass theStuff; 
    theStuff.test(); 
} 

Compiler ошибка:

In constructor ‘std::reverse_iterator<_Iterator>::reverse_iterator(const std::reverse_iterator<_Iter>&) 
       [with _Iter = std::_Rb_tree_const_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, 
       _Iterator = std::_Rb_tree_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >]’: 

junk3.cpp:19: instantiated from here 
error: no matching function for call to ‘std::_Rb_tree_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_Rb_tree_iterator(std::_Rb_tree_const_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >)’ 
candidates are: 
    std::_Rb_tree_iterator<_Tp>::_Rb_tree_iterator(std::_Rb_tree_node<_Tp>*) [with _Tp = std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >] 
    std::_Rb_tree_iterator<_Tp>::_Rb_tree_iterator() [with _Tp = std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >] 

    std::_Rb_tree_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, 
     std::allocator<char> > > >::_Rb_tree_iterator(const std::_Rb_tree_iterator<std::pair<const long int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) 
+0

Поскольку 'collection' является' const', 'secondLastIt' должен быть' const_reverse_iterator' как это то, что возвращает 'rbegin()'. Или просто используйте 'auto'. –

+0

Ошибка, кажется, думает, что вы пытаетесь создать не-const-итератор из const-итератора. – Altainia

ответ

0

Вам нужен const_reverse_iterator поскольку collection является const

template <typename T> 
    bool 
    isSecondLastTemplate(const T &collection, const typename T::const_iterator &searchItem) 
    { 
    typename T::const_reverse_iterator secondLastIt = collection.rbegin(); 
       ^^^^^^^^^^^^^^^^^^^^^^ 
    return true; 
    } 
+0

Спасибо за это. Работает сейчас. – Danny