reverse_iterator assignment Expression: cannot seek vector iterator after end

huangapple go评论73阅读模式
英文:

reverse_iterator assignment Expression:cannot seek vector iterator after end

问题

以下是您要翻译的代码部分:

#include <vector>
#include <iterator>
#include <iostream>
#include <list>
#include <algorithm>

using namespace std;

int main()
{
    list<int> ilst;
    vector<int> ivec{ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 };
    auto iter = ivec.crbegin() - 2;

    for (; iter != ivec.crend() + 3; iter--)
    {
        auto it = back_inserter(ilst);
        *it = *iter;
    }
    return 0;
}

程序执行到为 iter 赋值时报错:

表达式:无法在 vector 迭代器的末尾之后寻找。

这段代码有什么问题?有人能告诉我问题出在哪里吗?

英文:

A practice question on C++ primer Edition 5th:

> Given a vector that has ten elements,copy the elements from
> positions 3 through 7 in reverse order to a list.

#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;iostream&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;

using namespace std;

int main()
{
	list&lt;int&gt; ilst;
	vector&lt;int&gt; ivec{ 1,1,2,3,5,8,13,21,34,55 };
	auto iter = ivec.crbegin() - 2;
	
	for (; iter != ivec.crend() + 3; iter--)
	{
		auto it = back_inserter(ilst);
		*it = *iter;
	}
	return 0;
}

An error is reported when the program executes to assign a value to iter:
> Expression:cannot seek vector iterator after end.

What's wrong with the code?Can someone tell me where the problem is?

答案1

得分: 2

逆向迭代器从容器的末尾移动到容器的开头。因此,在逆向迭代器上调用 ++ 运算符会在容器中向左移动一个位置。

英文:

Reverse iterators go from end of the container to the beginning of the container. So calling ++ operator on the reverse iterator will move one position to left in the container.

#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;iostream&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;

using namespace std;

int main()
{
    list&lt;int&gt; ilst;
    vector&lt;int&gt; ivec{ 1,1,2,3,5,8,13,21,34,55 };
    for (auto it = ivec.crbegin() + 2; it != ivec.crbegin() + 7; it++)
    {
        ilst.push_back(*it);
    }

    for (auto x : ilst) cout &lt;&lt; x &lt;&lt; &#39; &#39;;
    return 0;
}

答案2

得分: 2

反向迭代器以相反的顺序遍历容器,这意味着将反向迭代器向前移动实际上会更接近容器的开头。同样,如果你向后迭代它,你会更接近容器的末尾。这意味着这行代码:

auto iter = ivec.crbegin() - 2;

越过了容器的边界(超出容器中最后一个元素的2个元素)。同样,这部分代码:

ivec.crend() + 3

越过容器的开头3个元素。

在这两种情况下,你引用了容器不拥有的内存,这会导致未定义的行为。显然,你想要的是获取一个指向容器的第7个元素的反向迭代器:

auto it = std::prev(std::crend(source), 7)

并且检查它永远不会超过指向第二个元素的反向迭代器(以包括第三个元素):

it != std::prev(std::crend(source), 2)

以下是我将如何重写你的解决方案的方式:

#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;

int main() {
    std::list&lt;int&gt; target;
    const std::vector&lt;int&gt; source{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for (auto it = source.size() &gt; 7 ? std::prev(std::crend(source), 7) : std::crbegin(source);
         it != std::prev(std::crend(source), 2); ++it) {
        target.push_back(*it);
    }

    return 0;
}
英文:

Reverse iterators iterate containers in reverse order, it means that when moving a reverse iterator forward, it actually moves closer to the beginning of the container. Likewise, if you iterate it backwards, you get closer to the end of the container. It means that this line:

auto iter = ivec.crbegin() - 2;

Goes beyond the bounds of the container (2 elements past the last element in the container). Also this part:

ivec.crend() + 3

Goes 3 elements past the beginning of the container.

In both scenarios you refer to memory which the container doesn't own and it causes undefined behavior. What you apparently want instead is to take a reverse iterator referring to the 7'th element of the container:

auto it = std::prev(std::crend(source), 7)

And check that it never goes beyond a reverse iterator referring to the second element (in order to include the third one):

it != std::prev(std::crend(source), 2)

Here is how I would rewrite you solution:

#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;

int main() {
    std::list&lt;int&gt; target;
    const std::vector&lt;int&gt; source{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    for (auto it = source.size() &gt; 7 ? std::prev(std::crend(source), 7) : std::crbegin(source);
         it != std::prev(std::crend(source), 2); ++it) {
        target.push_back(*it);
    }

    return 0;
}

huangapple
  • 本文由 发表于 2023年3月7日 13:56:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658470.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定