Namespaces
Variants
Views
Actions

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

From cppreference.com
< cpp‎ | named req
m (-copy invalidation note for ++r, it doesn't actually say that.. assignment invalidates, not increment)
m (fmt)
 
(25 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{cpp/concept/title|OutputIterator}}
+
{{cpp/named req/title|OutputIterator}}
{{cpp/concept/navbar}}
+
{{cpp/named req/navbar}}
  
An {{tt|OutputIterator}} is an {{concept|Iterator}} that can write to the pointed-to element.  
+
A {{named req|OutputIterator}} is a {{named req|Iterator}} that can write to the pointed-to element.  
  
An example of a type that implements {{tt|OutputIterator}} is [[cpp/iterator/ostream_iterator|std::ostream_iterator]].
+
An example of a type that implements {{named req/core|OutputIterator}} is [[cpp/iterator/ostream_iterator|std::ostream_iterator]].
  
When {{concept|ForwardIterator}}, {{concept|BidirectionalIterator}}, or {{concept|RandomAccessIterator}} satisfies the {{concept|OutputIterator}} requirements in addition to its own requirements, it is described as '''mutable'''.
+
When {{named req|ForwardIterator}}, {{named req|BidirectionalIterator}}, or {{named req|RandomAccessIterator}} satisfies the {{named req/core|OutputIterator}} requirements in addition to its own requirements, it is described as '''mutable'''.
  
 
===Requirements===
 
===Requirements===
 +
The type {{c|X}} satisfies {{named req/core|OutputIterator}} if
  
The type {{tt|X}} satisfies {{tt|OutputIterator}} if
+
* The type {{c|X}} satisfies {{named req|Iterator}}
 
+
* {{c|X}} is a class type or a pointer type
* The type {{tt|X}} satisfies {{concept|Iterator}}
+
* {{tt|T}} is a class type or a pointer type
+
  
 
And, given
 
And, given
* {{tt|o}} a value of some type that is writable to the output iterator
+
* {{c|o}}, a value of some type that is writable to the output iterator (there may be multiple types that are writable, e.g. if {{c|1= 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}},
+
* {{c|r}}, an lvalue of type {{c|X}},
  
 
The following expressions must be valid and have their specified effects
 
The following expressions must be valid and have their specified effects
 
{|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}} is not required to be dereferencable after this operation (it may not be possible to write to the same iterator twice)
+
|{{c|1=*r = o}}
 +
|(not used)
 +
|
 +
|{{c|r}} is dereferenceable
 +
|{{c|r}} is incrementable
 +
|After this operation {{c|r}} is not required to be dereferenceable and any copies of the previous value of {{c|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.
+
|
 +
|{{c|r}} is incrementable
 +
|{{c|r}} and {{c|++r}} designate the same iterator object, {{c|r}} is dereferenceable or past-the-end
 +
|After this operation {{c|r}} is not required to be incrementable and any copies of the previous value of {{c|r}} are no longer required to be dereferenceable or incrementable.
 
|-
 
|-
|{{c|r++}}|| convertible to {{c|const X&}} || {{c|
+
|{{c|r++}}
X temp {{=}} r;
+
|convertible to {{c|const X&}}
 +
|{{c|1=
 +
X temp = r;
 
++r;
 
++r;
 
return temp;
 
return temp;
 
}}
 
}}
| {{tt|r}} is incrementable
+
|
 +
|
 +
|
 
|-
 
|-
|{{c|*r++ {{=}} o}} || ||
+
|{{c|1=*r++ = o}}
| {{tt|r}} is incrementable
+
|(not used)
| {{tt|r}} is not required to be dereferencable after this operation.
+
|{{c|1=*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 {{c|operator*}} with an output iterator is on the left of an assignment: {{c|operator*}} may return a proxy object, which defines a member {{c|1= operator=}} (which may be a template).
 +
 
 +
Equality and inequality may not be defined for output iterators. Even if an {{c|1= operator==}} is defined, {{c|1= x == y}} need not imply {{c|1= ++x == ++y}}.
 +
 
 +
Assignment through the same value of an output iterator happens only once: algorithms on output iterators must be single-pass algorithms.
  
Equality and inequality may not be defined for output iterators.
+
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}}).
  
Assignment through the same value of the output iterator happens only once: algorithms on output iterators must be single-pass algorithms.
+
Pure output-only iterator is allowed to declare its {{c|iterator_traits<X>::value_type}}, {{c|iterator_traits<X>::difference_type}}, {{c|iterator_traits<X>::pointer}}, and {{c|iterator_traits<X>::reference}} to be {{c|void}} (and iterators such as {{lc|std::back_insert_iterator}} do just that{{rev inl|since=c++20| except for {{tt|difference_type}}, which is now defined to satisfy {{lc|std::output_iterator}} }}).
  
Examples of output iterators that are not forward iterators are {{lc|std::ostream_iterator}} and {{lc|std::ostreambuf_iterator}}.
+
===Standard library===
 +
The following standard library iterators are output iterators that are not forward iterators:
 +
* {{lc|std::ostream_iterator}}
 +
* {{lc|std::ostreambuf_iterator}}
 +
* {{lc|std::insert_iterator}}
 +
* {{lc|std::back_insert_iterator}}
 +
* {{lc|std::front_insert_iterator}}
  
 
===See also===
 
===See also===
* [[cpp/iterator|Iterator library]]
+
{{dsc begin}}
 +
{{dsc inc|cpp/iterator/dsc output_iterator}}
 +
{{see_also_iterator_library}}
 +
{{dsc end}}
  
[[de:cpp/concept/OutputIterator]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[es:cpp/concept/OutputIterator]]
+
[[fr:cpp/concept/OutputIterator]]
+
[[it:cpp/concept/OutputIterator]]
+
[[ja:cpp/concept/OutputIterator]]
+
[[pt:cpp/concept/OutputIterator]]
+
[[ru:cpp/concept/OutputIterator]]
+
[[zh:cpp/concept/OutputIterator]]
+

Latest revision as of 10:54, 25 September 2022

 
 
C++ named requirements
 

A LegacyOutputIterator is a LegacyIterator that can write to the pointed-to element.

An example of a type that implements LegacyOutputIterator is std::ostream_iterator.

When LegacyForwardIterator, LegacyBidirectionalIterator, or LegacyRandomAccessIterator satisfies the LegacyOutputIterator requirements in addition to its own requirements, it is described as mutable.

Contents

[edit] Requirements

The type X satisfies LegacyOutputIterator if

  • The type X satisfies LegacyIterator
  • X 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. 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 dereferenceable 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 and ++r designate the same iterator object, r is dereferenceable 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;

[edit] 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 issue 2035).

Pure output-only iterator is allowed to declare its iterator_traits<X>::value_type, iterator_traits<X>::difference_type, iterator_traits<X>::pointer, and iterator_traits<X>::reference to be void (and iterators such as std::back_insert_iterator do just that except for difference_type, which is now defined to satisfy std::output_iterator (since C++20)).

[edit] Standard library

The following standard library iterators are output iterators that are not forward iterators:

[edit] See also

specifies that a type is an output iterator for a given value type, that is, values of that type can be written to it and it can be both pre- and post-incremented
(concept) [edit]
Iterator library provides definitions for iterators, iterator traits, adaptors, and utility functions