从迭代器构造的反向迭代器是其先前的迭代器吗?

Ita*_*iwa 4 c++ reverse-iterator

https://en.cppreference.com/w/cpp/iterator/reverse_iterator上说:

std::reverse_iterator是一个迭代器适配器,可反转给定迭代器的方向。换句话说,当提供了双向迭代器时,将std::reverse_iterator生成一个新的迭代器,该迭代器将从基础双向迭代器定义的序列的末尾移动到开头。

对于由迭代器r构造的反向迭代器i,该关系&*r == &*(i-1)始终为true(只要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;

}
Run Code Online (Sandbox Code Playgroud)

输出:

0023FDAC :
0023FC9C : 13
0048C608 : 13
Run Code Online (Sandbox Code Playgroud)

为什么迭代器具有相同的值但在不同的地址上?

请问这&*r == &*(i-1)是不正确的吗?

Nat*_*ica 10

地址不同,因为您有不同的对象。 (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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0xed3c8c : 
0xed3c88 : 13
0xed3c88 : 13
Run Code Online (Sandbox Code Playgroud)

如您所见,由于迭代器指向相同的元素,因此地址是相同的。


请注意

&(*offEnd)
Run Code Online (Sandbox Code Playgroud)

是非法的并且是未定义的行为。没有对象,end()因此取消引用过去的结束迭代器是非法的。

  • 该代码压缩在MSVC ++ 14上。我认为这段代码中有一个UB。因为它在GCC上有效。 (3认同)