从指针或引用获取迭代器 [英] Obtain iterator from pointer or reference

查看:150
本文介绍了从指针或引用获取迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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



此处可能会出现此问题。似乎OP更希望其他人修改他的代码,而不是回答一般性问题,所以在我看来答案并不那么令人满意。此外,此处的答案似乎表明我们可以使用构造函数初始化迭代器,如下所示

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

但我无法找到std :: iterator类的构造函数的任何证据官方文档(我也没能在std :: vector< ...> :: iterator上找到任何文档)所以我很谨慎使用上面显示的构造函数,即使它编译。<​​/ p>

注意



我使用 std :: vector 作为上面的一个例子,但理想情况下我希望这适用于任何容器,例如 std :: list std :: 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 转换为迭代器。但这将取决于侵入式容器本身。


I would like to know if it is possible to obtain an iterator to an object inside a container (e.g. std::vector<...>) by only having access to the object inside the container, e.g. through a reference (which implies we have access to a pointer to it using the & operator). For example, normally we declare an iterator as

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

or

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

but in the first example we are most probably about to iterate through the container, in order, while in the second example we know the index of the object we require. I would like to know if we can obtain the iterator to an object without knowing at which index it resides in the container, but if we do have a reference or a pointer to it, as explained above.

It might appear that this question has already been asked here, but it seems more like the OP wanted others to fix his code, rather than answering the general question, so the answers are not so satisfactory in my opinion. Also, the answer here seems to say that we can initialize an iterator with a constructor, as shown below

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

but I have not been able to find any evidence of a constructor for the std::iterator class in the official documentation (and neither have I been able to find any documentation on std::vector<...>::iterator) so I am wary to use the constructor shown above, even if it compiles.

NOTE

I use std::vector as an example above, but ideally I would like this to work for any container, e.g. std::list or std::deque

解决方案

Specifically for std::vector (and other contiguous containers like std::string), given a pointer to an object in the vector p, we can simply do:

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

This is guaranteed by the contiguity contract. Note that random access is insufficient here, the above will not work for std::deque.

For any other container, there's no easy way of doing this. You'd have to just use find_if:

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


For intrusive containers, the iterator will be encoded into the object itself somehow so there will be some direct mechanism for converting p to an iterator. But that will be dependent on the intrusive container itself.

这篇关于从指针或引用获取迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆