取消引用分配给双倍增量的OutputIterator

eca*_*mur 5 c++ iterator increment language-lawyer post-increment

每(优秀)质询C++输出迭代增量后的要求,我们观察到,对于一提领和递增的值rOutputIterator类型X,和值o适当类型的,所述表达

*r++ = o;
Run Code Online (Sandbox Code Playgroud)

是有效的,并具有相同的语义

X a(r);
++r;
*a = o;
Run Code Online (Sandbox Code Playgroud)

但是,a如果r在中间期间增加不止一次,那么仍然可以解除引用吗?也就是说,这段代码有效吗?

X a(r);
++r;
++r;
*a = o;
Run Code Online (Sandbox Code Playgroud)

很难看出对值的操作如何影响对另一个值的操作的有效性,但是例如InputIterator(24.2.3)在以下条件下的后置条件下++r:

之前的任何值的副本r都不再需要可解除引用或属于其中==.

相关章节:24.2.2迭代器,24.2.4输出迭代器,17.6.3.1模板参数要求.

此外,如果这不是必须有效的,是否有任何情况下利用其无效性将有助于类型的实现(wrt效率,简单性),OutputIterator同时仍然遵守现有要求?

nkn*_*ght 3

这个问题在 2004 年作为缺陷 485被提出, n3066中的措辞澄清了这个问题,要求输出迭代器只需要支持一系列交替增量和取消引用/赋值。因此,在您的示例中,r在第一个之后不需要可递增++r,除非存在中间的取消引用/赋值。SGI 的STL也要求这种行为(参见脚注 3)。正如您上面提到的,n3225 的出现没有经过 n3066 的修复,因此提出了缺陷 2035 ;但遗憾的是,该修复并未进入 C++11 的发布版本 (ISO/IEC 14882:2011)。

此外,缺陷 2035 表示a(from X a(r++);) 不能像这样使用*a = 0

“在此操作之后 [即++r]r不再需要可递增,并且先前值的任何副本r不再需要可取消引用或可递增。”

在某些情况下,这可能有助于实现(就简单性而言):参见例如关于 的问题ostream_iterator,其中简单地返回 会忽略这种(无效的)双增量*this;只有取消引用/赋值才会导致ostream_iterator实际增加。