【问题标题】:C++ returning invalid iteratorC++ 返回无效的迭代器
【发布时间】:2021-09-18 16:48:38
【问题描述】:

我的任务是:

编写一个函数,将一对迭代器指向一个向量,然后 一个 int 值。在范围内查找该值并将迭代器返回到 请求的元素。

我对上述任务的实现是:

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

using data = vector<int>;
using iter = data::const_iterator;

iter contains(const data, iter, iter, int);

int main() {
    data numbers{1, 2, 5, 7, 9, 14, 18};
    iter b_iter = numbers.begin() + 2;
    iter e_iter = numbers.end();
    iter found = contains(numbers, b_iter, e_iter, 13);

    if (found == numbers.end())
        cout << "not found" << endl;
    else
        cout << *found << endl;

    return 0;
}

iter contains(const data container, iter b_iter, iter e_iter, int num) {
    while (b_iter != e_iter) {
        if (*b_iter == num)
            return b_iter;
        b_iter++;
    }

    return container.end();
}

如您所见,我从头到尾迭代,如果找到搜索值则返回。否则,函数返回迭代器以传递最后一个元素 (container.end())。但是这个程序将0 输出到控制台,我期望在控制台中not found。当更新我的函数的第一个参数以引用数据而不是像这样的值时:

iter contains(const data&, iter, iter, int);

功能按预期工作,not found 被打印到终端。为什么按值传递数据不能按预期工作?

【问题讨论】:

  • 迭代器与容器的特定实例(对象)相关。当您按值传递向量时,该函数会接收该向量的副本,该副本与您传递的迭代器无关。
  • 当按值传递时,data 将是一个副本,并且您返回另一个范围的结束迭代器。
  • 顺便说一句,std::find 比您写的包含更多。如果找不到,您可以返回e_iter 并去掉容器参数。
  • Prefer 前增量到后增量。

标签: c++ iterator


【解决方案1】:

container 按值传递时,它是从参数复制的新vector。那么对于return container.end();,返回的迭代器属于container,但与原来的vectornumbers无关。

你应该直接返回e_iter,不需要像STL算法那样传递vector

iter contains(iter b_iter, iter e_iter, int num) {
    while (b_iter != e_iter) {
        if (*b_iter == num)
            return b_iter;
        b_iter++; // or ++b_iter; for efficiency
    }

    return e_iter;
}

并通过与e_iter 进行比较来检查结果。

iter found = contains(b_iter, e_iter, 13);

if (found == e_iter)
    cout << "not found" << endl;
else
    cout << *found << endl;

【讨论】:

  • 感谢您的回答,但 e_iter 不一定是迭代器,可以传递最后一个元素。要求是takes a pair of iterators to a vector。所以我认为通过参考传递向量是更好的选择。
  • @ElginCahangirov 答案已修改。您正在传递一个范围,e_iter 始终是传递该范围中最后一个元素的那个。如何定义范围取决于您。
  • @ElginCahangirov 的“未找到迭代器”不一定是整个容器的end,而是您传递给contains 的范围的end。假设你只有两个迭代器(不是容器),一个指向存在,另一个指向范围的末尾,那么如果contains 返回第二个,你就知道元素没有找到
  • @463035818_is_not_a_number 如果搜索到的元素正好等于范围内的最后一个元素怎么办?
  • @ElginChangirov 也许您缺少的细节是:numbers.end() 不是容器中最后一个元素的迭代器。它是最后一个元素之后的元素的迭代器,这就是为什么我们可以使用它来指示“未找到”。 (当范围不是整个容器时,它的工作原理相同)
猜你喜欢
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多