从迭代器构造的反向迭代器是它的前一个迭代器吗?
Is a reverse iterator constructed from an iterator is its previous iterator?
在https://en.cppreference.com/w/cpp/iterator/reverse_iterator上说:
std::reverse_iterator
is an iterator adaptor that reverses the direction of a given iterator. In other words, when provided with a bidirectional iterator, std::reverse_iterator
produces a new iterator that moves from the end to the beginning of the sequence defined by the underlying bidirectional iterator.
For a reverse iterator r
constructed from an iterator i
, the relationship &*r == &*(i-1)
is always true (as long as r
is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.
所以我尝试了这段代码来了解更多信息:
int main() {
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 }; // fibonacci series
// deque has bi-directional iterators
std::deque<int>::iterator offEnd = di.end(); // one-past the last element in di
std::deque<int>::reverse_iterator r(offEnd); // constructing a reverse iterator from an iterator from deque<int> di
std::cout << &offEnd << " : " /*<< *r */ << std::endl;
std::cout << &(offEnd - 1) << " : " << *(offEnd - 1) << std::endl;
std::cout << &*r << " : " << *r << std::endl;
}
输出:
0023FDAC :
0023FC9C : 13
0048C608 : 13
为什么迭代器具有相同的值但在不同的地址???!!!
这是否意味着 &*r == &*(i-1)
不正确?
地址不同是因为你有不同的对象。 (offEnd - 1)
和 r
是不同的对象。因为他们是,所以他们有不同的地址。您需要做的是取消对迭代器的引用,然后获取该地址。这样做会给你
int main()
{
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 }; // fibonacci series
// deque has bi-directional iterators
std::deque<int>::iterator offEnd = di.end(); // one-past the last element in di
std::deque<int>::reverse_iterator r(offEnd); // constructing a reverse iterator from an iterator from deque<int> di
std::cout << &(*offEnd) << " : " /*<< *r */ << std::endl;
std::cout << &(*(offEnd - 1)) << " : " << *(offEnd - 1) << std::endl;
std::cout << &*r << " : " << *r << std::endl;
}
输出:
0xed3c8c :
0xed3c88 : 13
0xed3c88 : 13
正如您所见,地址是相同的,因为迭代器指向相同的元素。
请注意
&(*offEnd)
是非法的,是未定义的行为。 end()
处没有对象,因此取消对结束迭代器的引用是非法的。
原因很明显,你查询offEnd
和offEnd-1
的地址也是一样的。您正在查询迭代器的地址,如果您使用 -
-运算符在此迭代器内移动,该地址将保持不变。
在https://en.cppreference.com/w/cpp/iterator/reverse_iterator上说:
std::reverse_iterator
is an iterator adaptor that reverses the direction of a given iterator. In other words, when provided with a bidirectional iterator,std::reverse_iterator
produces a new iterator that moves from the end to the beginning of the sequence defined by the underlying bidirectional iterator.For a reverse iterator
r
constructed from an iteratori
, the relationship&*r == &*(i-1)
is always true (as long asr
is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.
所以我尝试了这段代码来了解更多信息:
int main() {
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 }; // fibonacci series
// deque has bi-directional iterators
std::deque<int>::iterator offEnd = di.end(); // one-past the last element in di
std::deque<int>::reverse_iterator r(offEnd); // constructing a reverse iterator from an iterator from deque<int> di
std::cout << &offEnd << " : " /*<< *r */ << std::endl;
std::cout << &(offEnd - 1) << " : " << *(offEnd - 1) << std::endl;
std::cout << &*r << " : " << *r << std::endl;
}
输出:
0023FDAC :
0023FC9C : 13
0048C608 : 13
为什么迭代器具有相同的值但在不同的地址???!!!
这是否意味着 &*r == &*(i-1)
不正确?
地址不同是因为你有不同的对象。 (offEnd - 1)
和 r
是不同的对象。因为他们是,所以他们有不同的地址。您需要做的是取消对迭代器的引用,然后获取该地址。这样做会给你
int main()
{
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 }; // fibonacci series
// deque has bi-directional iterators
std::deque<int>::iterator offEnd = di.end(); // one-past the last element in di
std::deque<int>::reverse_iterator r(offEnd); // constructing a reverse iterator from an iterator from deque<int> di
std::cout << &(*offEnd) << " : " /*<< *r */ << std::endl;
std::cout << &(*(offEnd - 1)) << " : " << *(offEnd - 1) << std::endl;
std::cout << &*r << " : " << *r << std::endl;
}
输出:
0xed3c8c :
0xed3c88 : 13
0xed3c88 : 13
正如您所见,地址是相同的,因为迭代器指向相同的元素。
请注意
&(*offEnd)
是非法的,是未定义的行为。 end()
处没有对象,因此取消对结束迭代器的引用是非法的。
原因很明显,你查询offEnd
和offEnd-1
的地址也是一样的。您正在查询迭代器的地址,如果您使用 -
-运算符在此迭代器内移动,该地址将保持不变。