SGI

输出迭代器

类别: 迭代器 组件类型: 概念

描述

输出迭代器是一种提供存储(但不一定访问)值序列机制的类型。输出迭代器在某种意义上是 输入迭代器 的反面,但它们具有更严格的接口:它们不一定支持成员访问或相等性,并且它们不一定具有关联的距离类型,甚至没有值类型 [1]。直观地说,输出迭代器就像一盘磁带:您可以将值写入当前位置,并且可以前进到下一个位置,但您不能读取值,也不能后退或倒带。

细化

可赋值默认可构造

关联类型

无。 [1]

符号

X 输出迭代器模型的类型
x, y 类型对象X

定义

如果x是类型为 的输出迭代器X,则表达式*x = t;将值t存储到x。请注意operator=,与其他 C++ 函数一样,可能会被重载;事实上,它甚至可能是一个模板函数。因此,一般来说,t可能是几种不同类型中的任何一种。类型T属于X的*值类型集*,如果对于类型为t的对象T, *x = t;是定义良好的,并且不需要对t. [1]

执行任何非平凡的转换。输出迭代器可能是*奇异的*,这意味着大多数操作(包括复制和解引用赋值)的结果都是未定义的。唯一保证支持的操作是将非奇异迭代器赋值给奇异迭代器。

输出迭代器可能是*可解引用的*,这意味着通过它进行赋值是定义良好的。可解引用迭代器始终是非奇异的,但非奇异迭代器不一定是可解引用的。

有效表达式

名称 表达式 类型要求 返回类型
默认构造函数
X x;
X()
   
复制构造函数 X(x)   X
复制构造函数 X y(x);或者X y = x;    
解引用赋值 *x = t t可转换为X. [1] 的值类型集中的类型
结果未使用 前缀递增   ++x
X& 后缀递增   (void) x++
void 后缀递增并赋值   的值类型集中的类型

*x++ = t;

名称 表达式 表达式语义 前提条件 语义
默认构造函数
X x;
X()
    x后置条件
复制构造函数 X(x) x可能是奇异的   是非奇异的*X(x) = t*x = t [2]
复制构造函数 等价于或者X x(y); y可能是奇异的   X x = y;*X(x) = t*x = t [2]
解引用赋值 *x = t x*y = tx是可解引用的。如果之前已经通过    
结果未使用 前缀递增 x进行过赋值,则已经进行过一次递增。 [3]x是可解引用的。x之前已经通过x [3] [4]   x进行过赋值。如果
X& 后缀递增 x进行过赋值,则已经进行过一次递增。 [3]x之前已经递增过,则已经通过 进行过一次赋值。指向可以存储值的下一个位置 x进行过赋值。如果
void 后缀递增并赋值 x*y = tx之前已经通过 进行过一次赋值。进行过赋值。 x进行过赋值。如果

等价于

(void) ++x

,则已经进行过一次递增。 [3] [4]

{*x = t; ++x; }

ostream_iterator

insert_iteratorfront_insert_iteratorback_insert_iterator*x = t注意front_insert_iterator[1] 其他迭代器类型,包括 平凡迭代器输入迭代器,定义了*值类型*的概念,即迭代器被解引用时返回的类型。然而,这个概念不适用于输出迭代器,因为解引用运算符(一元*x = toperator*operator=)不会为输出迭代器返回可用的值。解引用运算符可以使用的唯一上下文是通过输出迭代器进行赋值

。尽管 输入迭代器 和输出迭代器是大致对称的概念,但在访问和存储值方面有一个重要的区别:对于 输入迭代器x必须返回唯一的类型,但是对于输出迭代器,在表达式y中,没有理由要求y必须采用唯一的类型。 [5] 因此,输出迭代器不需要有任何唯一的“值类型”。

[2] 在任何时候,单个输出迭代器都应该只有一个活动副本。也就是说:在创建并使用输出迭代器x的副本x之后,不应再使用原始输出迭代器xx[3] 通过输出迭代器进行赋值应该与递增交替进行,并且在递增之前必须通过应该与递增进行赋值。任何其他操作顺序都会导致未定义的行为。也就是说{*x = t

; ++x; *x = t2; ++x}是可以接受的,但; ++x; ++x; *x = t2;}则不行。[4] 请注意,输出迭代器不需要定义相等比较。即使定义了operator==.

Xx == y*x = t也不一定意味着++x == ++y[5] 如果您正在实现输出迭代器类,定义的一种合理方法是将X::operator*()定义为返回某个私有类X::operator*()X_proxyX.

的对象,然后定义

X_proxy::operator=
[Silicon Surf] [STL Home]
。请注意,您可以重载 ,甚至将其定义为成员模板;这允许通过