检查std :: map的迭代器是否指向最后一个元素

时间:2016-06-28 15:09:00

标签: c++ dictionary iterator stdmap reverse-iterator

我(正向)迭代std :: map并想查找迭代器是否指向 second last 元素。我似乎无法在任何地方找到如何做到这一点。

我有:

bool
isSecondLastFile(const TDateFileInfoMap::const_iterator &tsFile)
{
    TDateFileInfoMap::reverse_iterator secondLastIt = mFileInfoMap.rbegin()  + 1;
    return (tsFile == secondLastIt);
}

TDateFileInfoMap是std :: map

我得到了:

error: no match for ‘operator==’ in ‘tsFile == secondLastIt’
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:287: note: candidates are: bool std::_Rb_tree_const_iterator<_Tp>::operator==(const std::_Rb_tree_const_iterator<_Tp>&) const [with _Tp = std::pair<const long int, TFileInfo>]

这是否意味着我无法比较正向和反向迭代器?

如何确定前向迭代器是否指向倒数第二个元素?

4 个答案:

答案 0 :(得分:4)

std::map's迭代器类型为BidirectionalIterator。只需递减end迭代器两次 - 首先得到最后一个元素,因为m.end()在结束位置后返回一个迭代器,然后再次得到倒数第二个元素:

auto penultimate = std::prev(m.end(), 2);

然后你可以简单地检查生成的迭代器是否相等:

auto it = m.begin();
it == penultimate;

see it live on Coliru

当然,如果程序中的其他逻辑无法保证地图 ,则应先检查地图

答案 1 :(得分:2)

  

这是否意味着我无法比较正向和反向迭代器?

是的,你无法直接比较它们。

您可以使用base()来获取基础的基础迭代器。

  

返回底层基迭代器。那是   std::reverse_iterator(it).base() == it

     

基础迭代器引用下一个元素(来自   std::reverse_iterator::iterator_type透视)元素   reverse_iterator目前正指向。那是&*(rit.base() - 1) == &*rit

e.g。

return (tsFile == (++secondLastIt).base());

BTW:mFileInfoMap.rbegin() + 1因为std::map的迭代器不是RandomAccessIterator而不会编译。你可以写:

TDateFileInfoMap::reverse_iterator secondLastIt = mFileInfoMap.rbegin();
++secondLastIt;

请注意,我们不会检查地图是空的还是只有一个元素。

答案 2 :(得分:0)

前向迭代器的简单解决方案:

template <typename ForwardIterator>
inline bool isNthLast(std::size_t n, ForwardIterator pos, ForwardIterator last) {
    for( ;; --n, ++pos) {
        if(n == 0) 
            return (pos == last);
        if(pos == last)
            return false;
    }
}

bool isSecondLastFile(TDateFileInfoMap::const_iterator sFile) {
    return isNthLast(2, sFile, mFileInfoMap.end());
}

答案 3 :(得分:0)

map<int,int> m;

// to iterate till fixed range in map

auto end =m.end();
end--; // end to second last;

for(auto itr = m.begin(); itr!=end;itr++){
  // do your operation
}