【问题标题】:std::map::rend() returning first element of array, not element beforestd::map::rend() 返回数组的第一个元素,而不是之前的元素
【发布时间】:2012-05-02 22:51:43
【问题描述】:

我正在尝试通过 std::map 反向迭代,遵循以下代码:http://www.cplusplus.com/reference/stl/map/rend/ 它说:

rend() 返回一个反向迭代器,它引用地图容器中第一个元素之前的元素,这被认为是它的反向结束。

请注意,rend 不是指与 begin 相同的元素,而是指它之前的元素。

map<float,int> m;
m.insert(pair<float,int>(.1,0));
m.insert(pair<float,int>(.4,5));
map<float,int>::reverse_iterator rend=m.rend();
map<float,int>::iterator begin=m.begin();

当我运行它时,rend 和 begin 都指向 m 的第一个元素 (.1,0),但显然它不应该,鉴于上面的通知。我觉得我犯了一些非常明显的错误,但我无法弄清楚它可能是什么。

(C++,MSVC2010)

【问题讨论】:

  • 您如何确定rend“指向”该项目?
  • 这不是一个明确的参考。你通过什么方式确定了rend指向的地方?如果取消引用 rend,则结果无效,因为这是未定义的行为。

标签: c++ stl stdmap


【解决方案1】:

我相信您缺少的一点是,如果您使用调试器检查这些值,rend()begin() 返回的值将包含相同的值。但是,迭代器类型的 operator* 成员仍然可以让您访问不同的对象。

技术细节:rend() 返回的值不能指向begin() 之前,因为那是无效的。因此决定rend() 应该包含begin() 的值,并且所有其他反向迭代器进一步移动一个位置。 operator* 对此进行了补偿并访问了正确的元素。

24.5.1 反向迭代器的第一段说:

类模板 reverse_iterator 是一个迭代器适配器,它从其底层迭代器定义的序列的末尾迭代到该序列的开头。反向迭代器与其对应的迭代器 i 之间的基本关系由身份建立:
&amp;*(reverse_iterator(i)) == &amp;*(i - 1)

【讨论】:

    【解决方案2】:

    我不确定您如何检查rend 指向的位置,但我运行了这个示例来反驳您的说法。

    int main() {
    
        map<float,int> m;
        m.insert(pair<float,int>(.1,0));
        m.insert(pair<float,int>(.4,5));
        map<float,int>::reverse_iterator rend=m.rend();
        map<float,int>::iterator begin=m.begin();
    
        for ( rend=m.rbegin() ; rend != m.rend(); rend++ )
        cout << rend->first << " => " << rend->second << endl;
    }
    

    输出:

    0.4 => 5
    0.1 => 0
    

    如果rend 指向第一个元素,则不会打印 0.1 => 0。

    这是我的例子。您必须展示您的代码在哪里实际得出结论,即rend 指向第一个元素。

    【讨论】:

    • 实际上,据我了解,问题是rend()begin() 指向同一个元素。但是在您的示例中,您不打印 rend() 元素
    • @ArtakBegnazaryan:那是因为rend() 不应该被打印。这就像说,让我们尝试访问并打印列表最后一个元素之后的空间。我的示例表明,由于rend 不指向第一个元素,因此循环不会在第一个元素处停止,而是在到达末尾时停止。如果rend 确实等于开始,则不会打印第一个元素,因为循环将在相等时终止。
    • 刚刚得到我的投票 :) 关键是我检查并打印了 rend() 的值,它真的等于 begin() 的值(我知道这取决于实现,并且标准未定义)。您的代码证明rend()begin() 指向的位置不同,但是它们的值可以相等。
    【解决方案3】:

    访问rend 指向的元素是未定义的行为。它很可能会为您提供容器中的第一个项目或使您的应用程序崩溃或您能想象到的任何事情。此元素只是一个占位符,用于在迭代时指示容器结束(同样适用于各种标准库容器的 end)。

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 2011-04-18
      • 2021-10-04
      • 2015-04-20
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多