Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/named req/OutputIterator"

From cppreference.com
< cpp‎ | named req
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}}|| || || {{tt|r}} is incrementable || {{tt|r}} (along with all copies of {{tt|r}}) is not required to be dereferencable after this operation: it may not be possible to write through the same iterator value twice
+
|{{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|X&}}||  
+
|{{c|++r}}
|{{c|&r {{==}} &++r}}, {{tt|r}} is incrementable
+
|{{c|X&}}
|{{tt|r}} is not required to be dereferencable after this operation.
+
|
 +
|{{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++}}|| convertible to {{c|const X&}} || {{c|
+
|{{c|r++}}
 +
|convertible to {{c|const X&}}
 +
|{{c|
 
X temp {{=}} r;
 
X temp {{=}} r;
 
++r;
 
++r;
 
return temp;
 
return temp;
 
}}
 
}}
| {{tt|r}} is incrementable
+
|
|{{tt|r}} is not required to be dereferencable after this operation.
+
|
 +
|
 
|-
 
|-
|{{c|*r++ {{=}} o}} || ||
+
|{{c|*r++ {{=}} o}}
| {{tt|r}} is incrementable
+
|(not used)
| {{tt|r}} (along with all copies of {{tt|r}}) is not required to be dereferencable after this operation.
+
|{{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

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. if operator= may be a template. There is no notion of value_type as for the input iterators)
  • r an lvalue of type X,

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;
return temp;

*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.

See also