3

以下代码编译得很好,v2用 from覆盖了值v1

std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<int> v2 = {6, 7, 8, 9, 10};

std::copy(v1.begin(), v1.end(), v2.begin());

的第三个参数std::copy是一个 OutputIterator。但是,Container 要求指定a.begin(),其中aContainer 对象应具有iterator定义为的返回类型:

任何满足前向迭代器要求的迭代器类别。

前向迭代器要求不包括输出迭代器的要求,那么上面的例子是未定义的吗?我使用迭代器作为输出迭代器,即使没有明显的保证它会是一个。

但是,我相当确定上面的代码是有效的,所以我的猜测是,您可以从有关容器的详细信息中推断出,返回的前向迭代器begin()实际上也支持输出迭代器的要求。在那种情况下,什么时候begin() 返回输出迭代器?仅当容器存在const或存在其他情况时?

4

2 回答 2

8

如果前向迭代器是可变的,则它们可以符合输出迭代器的规范,具体取决于序列的类型。它没有明确说明(不像他们输入迭代器需求的事实),但是如果我们看一下需求表

输出迭代器要求

我们可以去检查给定的前向迭代器是否符合它们:

*r = o
(§24.2.5/1): ifX是一个可变迭代器,reference是对T

可变引用是可赋值的(除非你有一个不可赋值的类型,显然)。

++r, r++,*r++ = o
(§24.2.5 Table 109) 前向迭代器要求

表 109 中的第一行与输出迭代器的要求相同,只是前向迭代器没有备注。第二行比输出迭代器更严格,因为它指定reference必须返回 a。

底线,如果你有一个可变的前向迭代器到一系列可复制分配的类型,你就有一个有效的输出迭代器

(从技术上讲,具有 aoperator=(...) const和可变成员的类型序列的常量迭代器也符合条件,但我们希望没有人会这样做。)

于 2012-09-26T19:00:56.650 回答
4

前向迭代器要求不包括输出迭代器的要求

这听起来倒退了。OutputIterators 需要满足的条件比 ForwardIterators少。(前向迭代器在递增后应该是可重用的,即将它们递增两次应该会产生相同的结果)。

因此,只要输出迭代器在算法完成之前保持有效,就可以了。爱荷华州:

auto outit = std::begin(v2);
std::advance(outit, v1.size()); // or: std::distance(std::begin(v1), std::end(v2))
// outit should still be valid here

编辑评论:

§ 24.2.1

进一步满足输出迭代器要求的迭代器称为mutable iterators。不可变迭代器称为constant iterators.

现在,让我找到将其联系在一起的一点,即vector::begin()返回可变随机访问迭代器。

信息

§ 24.2.5 前向迭代器 [forward.iterators]

1类或指针类型 X 满足前向迭代器的要求,如果

  • X 满足输入迭代器 (24.2.3) 的要求,
  • X 满足 DefaultConstructible 要求 (17.6.3.1),
  • 如果 X 是可变迭代器,则 reference 是对 T 的引用;如果 X 是一个 const 迭代器,reference 是对 const T 的引用,
  • 表 109 中的表达式是有效的并且具有指定的语义,并且
  • X 类型的对象提供多次通过保证,如下所述。
于 2012-09-26T18:49:20.327 回答