【问题标题】:C++ iterator to last element of a setC ++迭代器到集合的最后一个元素
【发布时间】:2016-12-23 13:34:09
【问题描述】:

我在 C++ 中有以下代码

#include <iostream>
#include <set>

using namespace std;

int main()
{
    set<int> a;
    int n;

    for(int i=0;i<3;i++){
      cin>>n;
      a.insert(n);
    }

    cout << *a.end();
    return 0;
}

为什么总是打印“3”而不是集合中的最大元素?将 cout &lt;&lt; *a.end(); 替换为 cout &lt;&lt; *--a.end(); 可以正常工作。

【问题讨论】:

  • end()not 指向最后一个元素,它指向 一个过去它。 C++ 范围在前面关闭,在后面打开:[begin, end)
  • This std::set::end reference 有一个很好的插图来说明它。
  • 我还以为后面也关了。谢谢!

标签: c++ iterator set


【解决方案1】:

只需使用指向集合中最后一个元素的*a.rbegin()

【讨论】:

    【解决方案2】:
    *a.end()
    

    未定义的行为。在 C++ 迭代器术语中,“结束”与“最后一个元素”的含义不同。

    cout &lt;&lt; *--a.end(); 替换cout &lt;&lt; *a.end(); 可以正常工作。

    考虑一个反向迭代器:*a.rbegin()

    请记住,begin()rbegin() 仅在容器不为空时才返回可取消引用的迭代器。对于空容器,begin() == end()rbegin() == rend()

    【讨论】:

    • 天啊!我一直使用 (--a.end()),但现在我知道最好的选择 ;)
    【解决方案3】:

    为什么总是打印“3”而不是最大的元素 设置好了吗?

    因为a.end()过去向量的末尾。它不包含任何有效数据,它是向量结束的标记。如:

    for(auto i = a.begin(); i != a.end(); ++i) 
        // do stuff with i
    

    编辑:(感谢 Nathan)取消引用 a.end() 会产生可怕的未定义行为。任何事情都可能发生:获取3,获取集合中的最后一个元素,甚至可以取消圣诞节!!!

    【讨论】:

    • 可能还想说是UB
    【解决方案4】:

    要找到集合的最后一个元素,我们可以做的是使用一个迭代器,它指向集合的最后一个元素,然后递减迭代器以到达最后一个元素,因为 set.end() 表示仅指向的迭代器在集合的末尾之外。

    auto it = s.end();
    it--;
    cout<<(*it)<<endl;
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 2011-02-10
      • 2021-03-05
      • 2020-08-16
      • 1970-01-01
      • 2011-08-21
      • 2018-01-08
      相关资源
      最近更新 更多