从指针或引用获取迭代器

Obtain iterator from pointer or reference

本文关键字:获取 迭代器 引用 指针      更新时间:2023-10-16

我想知道是否可以通过访问容器内的对象(例如std::vector<...>)来获得容器内对象的迭代器,例如通过引用(这意味着我们可以使用&运算符访问指向它的指针)。例如,通常我们将迭代器声明为

std::vector<int>::iterator = vec.begin();

std::vector<int>::iterator = next(vec.begin(), idx);

但是在第一个示例中,我们很可能要按顺序遍历容器,而在第二个示例中我们知道所需对象的索引。我想知道我们是否可以在不知道对象位于容器中的哪个索引的情况下获得对象的迭代器,但我们是否有指向它的引用或指针,如上所述。

这个问题似乎已经在这里被问过了,但OP似乎更希望其他人修复他的代码,而不是回答一般的问题,所以在我看来,答案并不那么令人满意。此外,这里的答案似乎是说,我们可以用构造函数初始化迭代器,如下所示

std::vector<int>::iterator it(...);

但我在官方文档中找不到任何std::迭代器类构造函数的证据(也找不到关于std::vector<…>::迭代程序的任何文档),所以我很谨慎地使用上面显示的构造函数,即使它是编译的。

注意

我使用std::vector作为上面的示例,但理想情况下,我希望它适用于任何容器,例如std::liststd::deque

特别是对于std::vector(以及像std::string这样的其他连续容器),给定指向向量p中对象的指针,我们可以简单地执行:

auto iter = v.begin() + std::distance(v.data(), p);

这是由邻接合同保证的。请注意,这里的随机访问是不够的,以上内容将不适用于std::deque

对于任何其他容器,都没有简单的方法可以做到这一点。你只需要使用find_if:

auto iter = std::find_if(c.begin(), c.end(), [p](auto const& o) { return &o == p; });

对于侵入式容器,迭代器将以某种方式编码到对象本身中,因此将有一些直接的机制将p转换为迭代器。但这将取决于侵入性容器本身。

您可以使用find函数——它返回一个迭代器——(几乎?)所有容器都支持它来查找对象。如果在operator==下有几个相等的对象,则进行迭代,直到找到具有相同地址的对象为止。

由于C++11可以使用关键字auto来推导类型,因此编写类型更容易。

如果我们知道索引,我们可以通过begin() + index得到它的迭代器。

如果我们不知道索引,我们可以从一开始就使用std::distance()和另一个迭代器,这将为我们提供一个相同元素的迭代器。

// if we know the index
auto it1 = begin(vec) + 4;
cout << *it1;
// if we don't know the index
auto p = begin(vec) + 3;
auto it2 = begin(vec) + distance(begin(vec), p+1);
cout << *it2;