Difference between revisions of "cpp/named req/OutputIterator"
m (and one more tweak) |
(this is more complex than I thought.. Applying LWG #2035 even though it's not in the doc, since it matches STL and real life) |
||
Line 16: | Line 16: | ||
And, given | And, given | ||
− | * {{tt|o}} a value of some type that is writable to the output iterator | + | * {{tt|o}} a value of some type that is writable to the output iterator (there may be multiple types that are writable, e.g. if {{tt|operator{{=}}}} may be a template. There is no notion of {{tt|value_type}} as for the input iterators) |
* {{tt|r}} an lvalue of type {{tt|X}}, | * {{tt|r}} an lvalue of type {{tt|X}}, | ||
Line 22: | Line 22: | ||
{|table class="wikitable" | {|table class="wikitable" | ||
|- | |- | ||
− | !Expression||Return||Equivalent expression||Post-conditions||Notes | + | !Expression||Return||Equivalent expression||Pre-condition||Post-conditions||Notes |
|- | |- | ||
− | |{{c|*r {{=}} o}}|| || | + | |{{c|*r {{=}} o}} |
+ | |(not used) | ||
+ | | | ||
+ | |{{tt|r}} is dereferencable | ||
+ | |{{tt|r}} is incrementable | ||
+ | |After this operation {{tt|r}} is not required to be dereferenceable and any copies of the previous value of {{tt|r}} are no longer required to be dereferenceable or incrementable. | ||
|- | |- | ||
− | |{{c|++r}} | + | |{{c|++r}} |
− | |{{c|&r {{==}} &++r}}, {{tt|r}} is | + | |{{c|X&}} |
− | |{{tt|r}} is not required to be | + | | |
+ | |{{tt|r}} is incrementable | ||
+ | |{{c|&r {{==}} &++r}}, {{tt|r}} is dereferencable or past-the-end | ||
+ | |After this operation {{tt|r}} is not required to be incrementable and any copies of the previous value of {{tt|r}} are no longer required to be dereferenceable or incrementable. | ||
|- | |- | ||
− | |{{c|r++}} | + | |{{c|r++}} |
+ | |convertible to {{c|const X&}} | ||
+ | |{{c| | ||
X temp {{=}} r; | X temp {{=}} r; | ||
++r; | ++r; | ||
return temp; | return temp; | ||
}} | }} | ||
− | | | + | | |
− | | | + | | |
+ | | | ||
|- | |- | ||
− | |{{c|*r++ {{=}} o}} | | + | |{{c|*r++ {{=}} o}} |
− | | {{ | + | |(not used) |
− | + | |{{c|*r {{=}} o; | |
+ | ++r;}} || | ||
+ | | | ||
+ | | | ||
+ | | | ||
|} | |} | ||
===Notes=== | ===Notes=== | ||
− | The only valid use of {{tt|operator*}} with an output iterator is on the left of an assignment | + | The only valid use of {{tt|operator*}} with an output iterator is on the left of an assignment: {{tt|operator*}} may return a proxy object, which defines a member {{tt|operator{{=}}}} (which may be a template) |
− | Equality and inequality may not be defined for output iterators. | + | Equality and inequality may not be defined for output iterators. Even if an {{tt|operator{{==}}}} is defined, {{tt|x {{==}} y}} need not imply {{tt|++x {{==}} ++y}}. |
Assignment through the same value of an output iterator happens only once: algorithms on output iterators must be single-pass algorithms. | Assignment through the same value of an output iterator happens only once: algorithms on output iterators must be single-pass algorithms. | ||
+ | |||
+ | Assignment through an output iterator is expected to alternate with incrementing. Double-increment is undefined behavior (C++ standard currently claims that double increment is supported, contrary to the STL documentation; this is [http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2035 LWG #2035]) | ||
Examples of output iterators that are not forward iterators are {{lc|std::ostream_iterator}} and {{lc|std::ostreambuf_iterator}}. | Examples of output iterators that are not forward iterators are {{lc|std::ostream_iterator}} and {{lc|std::ostreambuf_iterator}}. |
Revision as of 06:16, 22 August 2014
Template:cpp/concept/title Template:cpp/concept/navbar
An OutputIterator
is an Template:concept that can write to the pointed-to element.
An example of a type that implements OutputIterator
is std::ostream_iterator.
When Template:concept, Template:concept, or Template:concept satisfies the Template:concept requirements in addition to its own requirements, it is described as mutable.
Requirements
The type X
satisfies OutputIterator
if
- The type
X
satisfies Template:concept -
T
is a class type or a pointer type
And, given
-
o
a value of some type that is writable to the output iterator (there may be multiple types that are writable, e.g. ifoperator=
may be a template. There is no notion ofvalue_type
as for the input iterators) -
r
an lvalue of typeX
,
The following expressions must be valid and have their specified effects
Expression | Return | Equivalent expression | Pre-condition | Post-conditions | Notes | |
---|---|---|---|---|---|---|
*r = o | (not used) | r is dereferencable
|
r is incrementable
|
After this operation r is not required to be dereferenceable and any copies of the previous value of r are no longer required to be dereferenceable or incrementable.
| ||
++r | X& | r is incrementable
|
&r == &++r, r is dereferencable or past-the-end
|
After this operation r is not required to be incrementable and any copies of the previous value of r are no longer required to be dereferenceable or incrementable.
| ||
r++ | convertible to const X& | X temp = r; ++r; |
||||
*r++ = o | (not used) | *r = o; ++r; |
Notes
The only valid use of operator*
with an output iterator is on the left of an assignment: operator*
may return a proxy object, which defines a member operator=
(which may be a template)
Equality and inequality may not be defined for output iterators. Even if an operator==
is defined, x == y
need not imply ++x == ++y
.
Assignment through the same value of an output iterator happens only once: algorithms on output iterators must be single-pass algorithms.
Assignment through an output iterator is expected to alternate with incrementing. Double-increment is undefined behavior (C++ standard currently claims that double increment is supported, contrary to the STL documentation; this is LWG #2035)
Examples of output iterators that are not forward iterators are std::ostream_iterator and std::ostreambuf_iterator.