[readable.traits] # 24 Iterators library [[iterators]](./#iterators) ## 24.3 Iterator requirements [[iterator.requirements]](iterator.requirements#readable.traits) ### 24.3.2 Associated types [[iterator.assoc.types]](iterator.assoc.types#readable.traits) #### 24.3.2.2 Indirectly readable traits [readable.traits] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L808) To implement algorithms only in terms of indirectly readable types, it is often necessary to determine the value type that corresponds to a particular indirectly readable type[.](#1.sentence-1) Accordingly, it is required that if R is the name of a type that models the [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") concept ([[iterator.concept.readable]](iterator.concept.readable "24.3.4.2 Concept indirectly_­readable")), the typeiter_value_t be defined as the indirectly readable type's value type[.](#1.sentence-2) [🔗](#lib:indirectly_readable_traits) template struct *cond-value-type* { }; // *exposition only*templaterequires is_object_vstruct *cond-value-type* {using value_type = remove_cv_t;}; templateconcept [*has-member-value-type*](#concept:has-member-value-type "24.3.2.2 Indirectly readable traits [readable.traits]") = requires { typename T::value_type; }; // *exposition only*templateconcept [*has-member-element-type*](#concept:has-member-element-type "24.3.2.2 Indirectly readable traits [readable.traits]") = requires { typename T::element_type; }; // *exposition only*template struct indirectly_readable_traits { }; templatestruct indirectly_readable_traits: *cond-value-type* { }; templaterequires is_array_vstruct indirectly_readable_traits {using value_type = remove_cv_t>;}; templatestruct indirectly_readable_traits: indirectly_readable_traits { }; template<[*has-member-value-type*](#concept:has-member-value-type "24.3.2.2 Indirectly readable traits [readable.traits]") T>struct indirectly_readable_traits: *cond-value-type* { }; template<[*has-member-element-type*](#concept:has-member-element-type "24.3.2.2 Indirectly readable traits [readable.traits]") T>struct indirectly_readable_traits: *cond-value-type* { }; template<[*has-member-value-type*](#concept:has-member-value-type "24.3.2.2 Indirectly readable traits [readable.traits]") T>requires [*has-member-element-type*](#concept:has-member-element-type "24.3.2.2 Indirectly readable traits [readable.traits]")struct indirectly_readable_traits { }; template<[*has-member-value-type*](#concept:has-member-value-type "24.3.2.2 Indirectly readable traits [readable.traits]") T>requires [*has-member-element-type*](#concept:has-member-element-type "24.3.2.2 Indirectly readable traits [readable.traits]") &&[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), remove_cv_t>struct indirectly_readable_traits: *cond-value-type* { }; template using iter_value_t = *see below*; [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L874) Let RI be remove_cvref_t[.](#2.sentence-1) The type iter_value_t denotes - [(2.1)](#2.1) indirectly_readable_traits​::​value_type if iterator_traits names a specialization generated from the primary template, and - [(2.2)](#2.2) iterator_traits​::​value_type otherwise[.](#2.sentence-2) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L887) Class template indirectly_readable_traits may be specialized on program-defined types[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L891) [*Note [1](#note-1)*: Some legacy output iterators define a nested type named value_type that is an alias for void[.](#4.sentence-1) These types are not [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") and have no associated value types[.](#4.sentence-2) — *end note*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L899) [*Note [2](#note-2)*: Smart pointers like shared_ptr are [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") and have an associated value type, but a smart pointer like shared_ptr is not [indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_­readable [iterator.concept.readable]") and has no associated value type[.](#5.sentence-1) — *end note*]