C++ 从指针或引用获取迭代器

C++ 从指针或引用获取迭代器,c++,pointers,iterator,containers,C++,Pointers,Iterator,Containers,我想知道,如果只通过引用(这意味着我们可以使用&操作符访问容器内的对象),是否有可能获得容器内对象的迭代器(例如std::vector)。例如,通常我们将迭代器声明为 std::vector<int>::iterator = vec.begin(); std::vector::iterator=vec.begin(); 或 std::vector::iterator=next(vec.begin(),idx); 但在第一个示例中,我们很可能要按顺序遍历容器,而在第二个示例中,我

我想知道,如果只通过引用(这意味着我们可以使用
&
操作符访问容器内的对象),是否有可能获得容器内对象的迭代器(例如
std::vector
)。例如,通常我们将迭代器声明为

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

std::vector::iterator=next(vec.begin(),idx);
但在第一个示例中,我们很可能要按顺序遍历容器,而在第二个示例中,我们知道所需对象的索引。我想知道我们是否可以在不知道对象在容器中的索引的情况下获得对象的迭代器,但是我们是否有一个指向它的引用或指针,如上所述

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

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

注意


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

特别适用于
std::vector
(以及其他连续容器,如
std::string
),给定指向向量
p
中对象的指针,我们可以简单地做到:

auto iter = v.begin() + std::distance(v.data(), p);
这由毗连合同保证。请注意,此处的随机访问是不够的,上述方法不适用于
std::deque

对于任何其他容器,都没有简单的方法可以做到这一点。如果,您只需使用
find\u即可:

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


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

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

由于C++11可以使用关键字auto来推断类型,因此可以更轻松地编写类型

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

如果我们不知道索引,我们可以使用from begin和另一个迭代器,这将为同一个元素提供一个迭代器

// 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;
//如果我们知道索引
自动it1=开始(vec)+4;

你能浏览一下索引吗
vec.begin()+(pos-&vec[0])
@KonradKapp那么你应该寻找关于如何找到索引的问题;-)@dyp是的,很抱歉第一轮不清楚。我在问题上加了一条注释。我更喜欢使用迭代器,因为我希望将它用作for循环中的中断条件。但这与问题无关:)问题更一般地在于,是否可以通过这种方式获得迭代器(虽然看起来应该很容易),调试迭代器实现可能希望在迭代器中存储指向某个簿记对象的指针;在这种情况下,仅仅从元素的引用或指针构造迭代器可能是不可能的(因为元素的位置和簿记对象的位置是不相关的)。当然,人们总是可以实现一些全局LUT,但这很快就会变得丑陋/缓慢。因为迭代器的类型很多,所以不太可能为所有迭代器找到统一的解决方法。当然,您可以创建自己选择的迭代器并进行迭代,直到它与给定的项匹配为止。试图使用指向驻留在不同容器中的对象(或根本没有)的指针来恢复迭代器将失败。@DietmarKühl要清楚,当你说哪个容器时,实际上是指哪个类型的容器(例如,它是
vector
list
还是
deque
),而不是容器的哪个实例?(例如在
vector
?)的实例之间,@KonradKapp他指的是哪个实例。@KonradKapp否,您需要知道需要调用哪个实例
begin
。@KonradKapp:我指的是实例:如果您有两个向量,
v1
v2
以及您的指针(或引用)
p
指向其中一个容器中的元素,您需要知道元素指向两个容器中的哪一个。操作
std::distance(v.data(),p)
未定义,除非
p
处于半开范围
v.data()
v.data()+v.size()
// 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;