2012-07-12 170 views
9

例如,以下是可能的:获取迭代器引用的指向STL容器的指针?

std::set<int> s; 
std::set<int>::iterator it = s.begin(); 

不知对面是可能的,比方说,

std::set<int>* pSet = it->**getContainer**(); // something like this... 
+0

我很想知道为什么要这样。 – chris 2012-07-12 04:32:28

+0

我想要做的是在某些遍历(某些其他数据结构)期间保存迭代器的状态,以便在下次访问时增加迭代器。如果以上是可能的,那么我不必将引用/指针保留在容器本身,而只是指向该迭代器的指针。 – 2012-07-12 04:38:35

回答

13

不,没有做到这一点没有可移植的方法。

迭代器可能甚至没有对容器的参考。例如,对于std::array<T, N>std::vector<T>,实现都可以使用T*作为iterator类型,因为两者都将它们的元素存储为数组。另外,迭代器比容器更通用,并且并非所有迭代器都指向容器(例如,有输入和输出迭代器可以读取和写入流)。

+0

这是旧的,但我有一个非常小的问题。假设一个迭代器(不一定来自STL)确实来自一个容器,它可能会或可能不会拥有一个指向其原始包含器的指针/引用。但是如果是这样,那么容器的类型和容器本身对迭代器的用户是绝对已知的,他们不是吗?当然,除非容器的指针/引用被定义为私有的,但为什么程序员想隐藏这个呢? – Mark 2016-08-18 16:31:47

5

不可以。您必须记住迭代器来自的容器,当您找到迭代器时。

这个限制的一个可能的原因是指针被认为是有效的迭代器,并且没有办法要求指针来指出它来自哪里(例如,如果你将4个元素指向一个数组,你能告诉阵列的开始在哪里?)。

2

至少有一个std迭代器和一些欺骗是可能的。 std::back_insert_iterator需要一个指向容器的指针来调用其方法push_back。而且这个指针只有protected

#include <iterator> 

template <typename Container> 
struct get_a_pointer_iterator : std::back_insert_iterator<Container> { 
    typedef std::back_insert_iterator<Container> base; 
    get_a_pointer_iterator(Container& c) : base(c) {} 
    Container* getPointer(){ return base::container;} 
}; 

#include <iostream> 
int main() { 
    std::vector<int> x{1}; 
    auto p = get_a_pointer_iterator<std::vector<int>>(x); 
    std::cout << (*p.getPointer()).at(0); 
} 

这是没有用之实践的过程中,而仅仅是一个std迭代器确实带有一个指向其容器的一个例子,虽然是比较特别的一个(例如递增std::back_insert_iterator是一个空操作)。使用迭代器的重点不在于知道元素来自哪里。另一方面,如果你想要一个可以让你得到一个指向容器的指针的迭代器,你可以写一个。