eca*_*mur 5 c++ iterator increment language-lawyer post-increment
每(优秀)质询C++输出迭代增量后的要求,我们观察到,对于一提领和递增的值r
的OutputIterator
类型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
同时仍然遵守现有要求?
这个问题在 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
实际增加。