减少std :: map的结尾

Bha*_*wan 26 c++ stl

这是我的代码:

#include <iostream>
#include <map>
using namespace std;

int main() {
    map<int , int > myMap;

    map<int , int>::iterator it;

    myMap.insert(pair<int , int>(1,2));
    myMap.insert(pair<int , int>(671,223));
    myMap.insert(pair<int , int>(353,245352));

    it = myMap.end() - 1;

    cout << it->first << it->second << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译此代码会产生以下编译错误:

error: no match for ‘operator-’ (operand types are ‘std::map<int, int>::iterator {aka std::_Rb_tree_iterator<std::pair<const int, int> >}’ and ‘int’)
  it = myMap.end() - 1;
Run Code Online (Sandbox Code Playgroud)

我不知道为什么我会收到此错误,因为我认为所有类型的迭代器都允许算术运算.

Sto*_*ica 40

并非所有迭代器类别都支持算术运算,这是一种误解.如果您的目标是编写更多通用代码,则可以使用std::prev:

it = std::prev(myMap.end());
Run Code Online (Sandbox Code Playgroud)

它期望一个双向迭代器,它std::map是迭代器.如果要将迭代器移动多个步骤,它还可以接受第二个参数,该参数指定移动迭代器的距离.

另外,当你传递一个随机访问迭代器时,它将与算术一样快.

  • @Angew或者,为了避免为此提取整个提升,`it = myMap.end(); --IT;`.(但是如果你*仍然*不能使用C++ 11,那么我强烈建议使用boost - 对于`boost :: shared_ptr`,`boost :: noncopyable`和`BOOST_FOREACH`,如果没有别的话.) (7认同)
  • @YSC如果有人想要违反标准做法的代码,因此在"每分钟WTF"的众所周知的代码质量度量上得分很低,是的,可以.另外,最好用一些重的`enable_if'来限制它只用于迭代器,因为像这样的模板非常贪婪.另外,你不能在"标准"里合法地做到这一点,而ADL可以把它拿起来.总之,我不会这样做. (3认同)

Som*_*ude 17

我建议您阅读不同的迭代器类别,并了解它们可用的操作.

更具体地说,std::map迭代器是一个双向迭代器,它没有二进制减法.