从指针或引用

时间:2016-05-08 15:27:58

标签: c++ pointers iterator containers

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

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

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

但是在第一个例子中,我们很可能要按顺序迭代容器,而在第二个例子中,我们知道我们需要的对象的索引。我想知道我们是否可以获取对象的迭代器而不知道它驻留在容器中的哪个索引,但是如果我们确实有一个引用或指向它的指针,如上所述。

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

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

但我在官方文档中找不到std :: iterator类的构造函数的任何证据(我也没能找到关于std :: vector&lt; ...&gt;的任何文档: :iterator)所以我很谨慎使用上面显示的构造函数,即使它是编译的。

注意

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

3 个答案:

答案 0 :(得分:9)

特别是对于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转换为迭代器的直接机制。但这将取决于侵入式容器本身。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

从C ++ 11开始,您可以使用关键字auto来推断类型,这样可以更轻松地编写类型。

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

如果我们不知道索引,我们可以使用begin的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;