[move.iterators] # 24 Iterators library [[iterators]](./#iterators) ## 24.5 Iterator adaptors [[predef.iterators]](predef.iterators#move.iterators) ### 24.5.4 Move iterators and sentinels [move.iterators] #### [24.5.4.1](#general) General [[move.iterators.general]](move.iterators.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4760) Class template move_iterator is an iterator adaptor with the same behavior as the underlying iterator except that its indirection operator implicitly converts the value returned by the underlying iterator's indirection operator to an rvalue[.](#general-1.sentence-1) Some generic algorithms can be called with move iterators to replace copying with moving[.](#general-1.sentence-2) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4768) [*Example [1](#general-example-1)*: list s;// populate the list s vector v1(s.begin(), s.end()); // copies strings into v1 vector v2(make_move_iterator(s.begin()), make_move_iterator(s.end())); // moves strings into v2 — *end example*] #### [24.5.4.2](#move.iterator) Class template move_iterator [[move.iterator]](move.iterator) [🔗](#lib:move_iterator) namespace std {templateclass move_iterator {public:using iterator_type = Iterator; using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t; using difference_type = iter_difference_t; using pointer = Iterator; using reference = iter_rvalue_reference_t; constexpr move_iterator(); constexpr explicit move_iterator(Iterator i); template constexpr move_iterator(const move_iterator& u); template constexpr move_iterator& operator=(const move_iterator& u); constexpr const Iterator& base() const & noexcept; constexpr Iterator base() &&; constexpr reference operator*() const; constexpr move_iterator& operator++(); constexpr auto operator++(int); constexpr move_iterator& operator--(); constexpr move_iterator operator--(int); constexpr move_iterator operator+(difference_type n) const; constexpr move_iterator& operator+=(difference_type n); constexpr move_iterator operator-(difference_type n) const; constexpr move_iterator& operator-=(difference_type n); constexpr reference operator[](difference_type n) const; template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]") S>friend constexpr booloperator==(const move_iterator& x, const move_sentinel& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") S>friend constexpr iter_difference_toperator-(const move_sentinel& x, const move_iterator& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") S>friend constexpr iter_difference_toperator-(const move_iterator& x, const move_sentinel& y); friend constexpr iter_rvalue_reference_t iter_move(const move_iterator& i)noexcept(noexcept(ranges::iter_move(i.current))); template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]") Iterator2>friend constexpr void iter_swap(const move_iterator& x, const move_iterator& y)noexcept(noexcept(ranges::iter_swap(x.current, y.current))); private: Iterator current; // *exposition only*};} [1](#move.iterator-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4838) The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_concept is defined as follows: - [(1.1)](#move.iterator-1.1) If Iterator models [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]"), then iterator_concept denotes random_access_iterator_tag[.](#move.iterator-1.1.sentence-1) - [(1.2)](#move.iterator-1.2) Otherwise, if Iterator models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]"), then iterator_concept denotes bidirectional_iterator_tag[.](#move.iterator-1.2.sentence-1) - [(1.3)](#move.iterator-1.3) Otherwise, if Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]"), then iterator_concept denotes forward_iterator_tag[.](#move.iterator-1.3.sentence-1) - [(1.4)](#move.iterator-1.4) Otherwise, iterator_concept denotes input_iterator_tag[.](#move.iterator-1.4.sentence-1) [2](#move.iterator-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4855) The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category is defined if and only if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")iterator_traits​::​iterator_category is valid and denotes a type[.](#move.iterator-2.sentence-1) In that case, iterator_category denotes - [(2.1)](#move.iterator-2.1) random_access_iterator_tag if the typeiterator_traits<​Iterator>​::​iterator_category models[derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_­from [concept.derived]"), and - [(2.2)](#move.iterator-2.2) iterator_traits<​Iterator>​::​iterator_category otherwise[.](#move.iterator-2.sentence-2) #### [24.5.4.3](#move.iter.requirements) Requirements [[move.iter.requirements]](move.iter.requirements) [1](#move.iter.requirements-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4873) The template parameter Iterator shall either meet the *Cpp17InputIterator* requirements ([[input.iterators]](input.iterators "24.3.5.3 Input iterators")) or model [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") ([[iterator.concept.input]](iterator.concept.input "24.3.4.9 Concept input_­iterator"))[.](#move.iter.requirements-1.sentence-1) Additionally, if any of the bidirectional traversal functions are instantiated, the template parameter shall either meet the *Cpp17BidirectionalIterator* requirements ([[bidirectional.iterators]](bidirectional.iterators "24.3.5.6 Bidirectional iterators")) or model [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12 Concept bidirectional_­iterator [iterator.concept.bidir]") ([[iterator.concept.bidir]](iterator.concept.bidir "24.3.4.12 Concept bidirectional_­iterator"))[.](#move.iter.requirements-1.sentence-2) If any of the random access traversal functions are instantiated, the template parameter shall either meet the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")) or model[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept random_­access_­iterator"))[.](#move.iter.requirements-1.sentence-3) #### [24.5.4.4](#move.iter.cons) Construction and assignment [[move.iter.cons]](move.iter.cons) [🔗](#lib:move_iterator,constructor) `constexpr move_iterator(); ` [1](#move.iter.cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4895) *Effects*: Value-initializes current[.](#move.iter.cons-1.sentence-1) [🔗](#lib:move_iterator,constructor_) `constexpr explicit move_iterator(Iterator i); ` [2](#move.iter.cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4907) *Effects*: Initializes current with std​::​move(i)[.](#move.iter.cons-2.sentence-1) [🔗](#lib:move_iterator,constructor__) `template constexpr move_iterator(const move_iterator& u); ` [3](#move.iter.cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4919) *Constraints*: is_same_v is false andconst U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")[.](#move.iter.cons-3.sentence-1) [4](#move.iter.cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4924) *Effects*: Initializes current with u.current[.](#move.iter.cons-4.sentence-1) [🔗](#lib:operator=,move_iterator) `template constexpr move_iterator& operator=(const move_iterator& u); ` [5](#move.iter.cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4935) *Constraints*: is_same_v is false,const U& models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"), and[assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]") is modeled[.](#move.iter.cons-5.sentence-1) [6](#move.iter.cons-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4941) *Effects*: Assigns u.current tocurrent[.](#move.iter.cons-6.sentence-1) [7](#move.iter.cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4946) *Returns*: *this[.](#move.iter.cons-7.sentence-1) #### [24.5.4.5](#move.iter.op.conv) Conversion [[move.iter.op.conv]](move.iter.op.conv) [🔗](#lib:base,move_iterator) `constexpr const Iterator& base() const & noexcept; ` [1](#move.iter.op.conv-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4959) *Returns*: current[.](#move.iter.op.conv-1.sentence-1) [🔗](#lib:base,move_iterator_) `constexpr Iterator base() &&; ` [2](#move.iter.op.conv-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4970) *Returns*: std​::​move(current)[.](#move.iter.op.conv-2.sentence-1) #### [24.5.4.6](#move.iter.elem) Element access [[move.iter.elem]](move.iter.elem) [🔗](#lib:operator*,move_iterator) `constexpr reference operator*() const; ` [1](#move.iter.elem-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4983) *Effects*: Equivalent to: return ranges​::​iter_move(current); [🔗](#lib:operator%5b%5d,move_iterator) `constexpr reference operator[](difference_type n) const; ` [2](#move.iter.elem-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L4994) *Effects*: Equivalent to: return ranges​::​iter_move(current + n); #### [24.5.4.7](#move.iter.nav) Navigation [[move.iter.nav]](move.iter.nav) [🔗](#lib:operator++,move_iterator) `constexpr move_iterator& operator++(); ` [1](#move.iter.nav-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5007) *Effects*: As if by ++current[.](#move.iter.nav-1.sentence-1) [2](#move.iter.nav-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5011) *Returns*: *this[.](#move.iter.nav-2.sentence-1) [🔗](#lib:operator++,move_iterator_) `constexpr auto operator++(int); ` [3](#move.iter.nav-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5022) *Effects*: If Iterator models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_­iterator [iterator.concept.forward]"), equivalent to:move_iterator tmp = *this;++current;return tmp; Otherwise, equivalent to ++current[.](#move.iter.nav-3.sentence-2) [🔗](#lib:operator--,move_iterator) `constexpr move_iterator& operator--(); ` [4](#move.iter.nav-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5039) *Effects*: As if by --current[.](#move.iter.nav-4.sentence-1) [5](#move.iter.nav-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5043) *Returns*: *this[.](#move.iter.nav-5.sentence-1) [🔗](#lib:operator--,move_iterator_) `constexpr move_iterator operator--(int); ` [6](#move.iter.nav-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5054) *Effects*: As if by:move_iterator tmp = *this;--current;return tmp; [🔗](#lib:operator+,move_iterator) `constexpr move_iterator operator+(difference_type n) const; ` [7](#move.iter.nav-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5070) *Returns*: move_iterator(current + n)[.](#move.iter.nav-7.sentence-1) [🔗](#lib:operator+=,move_iterator) `constexpr move_iterator& operator+=(difference_type n); ` [8](#move.iter.nav-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5081) *Effects*: As if by: current += n; [9](#move.iter.nav-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5085) *Returns*: *this[.](#move.iter.nav-9.sentence-1) [🔗](#lib:operator-,move_iterator) `constexpr move_iterator operator-(difference_type n) const; ` [10](#move.iter.nav-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5096) *Returns*: move_iterator(current - n)[.](#move.iter.nav-10.sentence-1) [🔗](#lib:operator-=,move_iterator) `constexpr move_iterator& operator-=(difference_type n); ` [11](#move.iter.nav-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5107) *Effects*: As if by: current -= n; [12](#move.iter.nav-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5111) *Returns*: *this[.](#move.iter.nav-12.sentence-1) #### [24.5.4.8](#move.iter.op.comp) Comparisons [[move.iter.op.comp]](move.iter.op.comp) [🔗](#lib:operator==,move_iterator) `template constexpr bool operator==(const move_iterator& x, const move_iterator& y); template<[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]") S> friend constexpr bool operator==(const move_iterator& x, const move_sentinel& y); ` [1](#move.iter.op.comp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5129) *Constraints*: x.base() == y.base() is well-formed and convertible to bool[.](#move.iter.op.comp-1.sentence-1) [2](#move.iter.op.comp-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5134) *Returns*: x.base() == y.base()[.](#move.iter.op.comp-2.sentence-1) [🔗](#lib:operator%3c,move_iterator) `template constexpr bool operator<(const move_iterator& x, const move_iterator& y); ` [3](#move.iter.op.comp-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5146) *Constraints*: x.base() < y.base() is well-formed and convertible to bool[.](#move.iter.op.comp-3.sentence-1) [4](#move.iter.op.comp-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5151) *Returns*: x.base() < y.base()[.](#move.iter.op.comp-4.sentence-1) [🔗](#lib:operator%3e,move_iterator) `template constexpr bool operator>(const move_iterator& x, const move_iterator& y); ` [5](#move.iter.op.comp-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5163) *Constraints*: y.base() < x.base() is well-formed and convertible to bool[.](#move.iter.op.comp-5.sentence-1) [6](#move.iter.op.comp-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5168) *Returns*: y < x[.](#move.iter.op.comp-6.sentence-1) [🔗](#lib:operator%3c=,move_iterator) `template constexpr bool operator<=(const move_iterator& x, const move_iterator& y); ` [7](#move.iter.op.comp-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5180) *Constraints*: y.base() < x.base() is well-formed and convertible to bool[.](#move.iter.op.comp-7.sentence-1) [8](#move.iter.op.comp-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5185) *Returns*: !(y < x)[.](#move.iter.op.comp-8.sentence-1) [🔗](#lib:operator%3e=,move_iterator) `template constexpr bool operator>=(const move_iterator& x, const move_iterator& y); ` [9](#move.iter.op.comp-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5197) *Constraints*: x.base() < y.base() is well-formed and convertible to bool[.](#move.iter.op.comp-9.sentence-1) [10](#move.iter.op.comp-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5202) *Returns*: !(x < y)[.](#move.iter.op.comp-10.sentence-1) [🔗](#lib:operator%3c=%3e,move_iterator) `template Iterator2> constexpr compare_three_way_result_t operator<=>(const move_iterator& x, const move_iterator& y); ` [11](#move.iter.op.comp-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5216) *Returns*: x.base() <=> y.base()[.](#move.iter.op.comp-11.sentence-1) #### [24.5.4.9](#move.iter.nonmember) Non-member functions [[move.iter.nonmember]](move.iter.nonmember) [🔗](#lib:operator-,move_iterator_) `template constexpr auto operator-( const move_iterator& x, const move_iterator& y) -> decltype(x.base() - y.base()); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") S> friend constexpr iter_difference_t operator-(const move_sentinel& x, const move_iterator& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]") S> friend constexpr iter_difference_t operator-(const move_iterator& x, const move_sentinel& y); ` [1](#move.iter.nonmember-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5238) *Returns*: x.base() - y.base()[.](#move.iter.nonmember-1.sentence-1) [🔗](#lib:operator+,move_iterator_) `template constexpr move_iterator operator+(iter_difference_t n, const move_iterator& x); ` [2](#move.iter.nonmember-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5251) *Constraints*: x.base() + n is well-formed and has type Iterator[.](#move.iter.nonmember-2.sentence-1) [3](#move.iter.nonmember-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5255) *Returns*: x + n[.](#move.iter.nonmember-3.sentence-1) [🔗](#lib:iter_move,move_iterator) `friend constexpr iter_rvalue_reference_t iter_move(const move_iterator& i) noexcept(noexcept(ranges::iter_move(i.current))); ` [4](#move.iter.nonmember-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5268) *Effects*: Equivalent to: return ranges​::​iter_move(i.current); [🔗](#lib:iter_swap,move_iterator) `template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_­swappable [alg.req.ind.swap]") Iterator2> friend constexpr void iter_swap(const move_iterator& x, const move_iterator& y) noexcept(noexcept(ranges::iter_swap(x.current, y.current))); ` [5](#move.iter.nonmember-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5282) *Effects*: Equivalent to: ranges​::​iter_swap(x.current, y.current)[.](#move.iter.nonmember-5.sentence-1) [🔗](#lib:make_move_iterator) `template constexpr move_iterator make_move_iterator(Iterator i); ` [6](#move.iter.nonmember-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5294) *Returns*: move_iterator(std​::​move(i))[.](#move.iter.nonmember-6.sentence-1) #### [24.5.4.10](#move.sentinel) Class template move_sentinel [[move.sentinel]](move.sentinel) [1](#move.sentinel-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5301) Class template move_sentinel is a sentinel adaptor useful for denoting ranges together with move_iterator[.](#move.sentinel-1.sentence-1) When an input iterator typeI and sentinel type S model [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]"),move_sentinel and move_iterator model[sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]"), move_iterator> as well[.](#move.sentinel-1.sentence-2) [2](#move.sentinel-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5308) [*Example [1](#move.sentinel-example-1)*: A move_if algorithm is easily implemented withcopy_if using move_iterator and move_sentinel:template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_­iterator [iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_­for [iterator.concept.sentinel]") S, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept weakly_­incrementable [iterator.concept.winc]") O, [indirect_unary_predicate](indirectcallable.indirectinvocable#concept:indirect_unary_predicate "24.3.6.3 Indirect callables [indirectcallable.indirectinvocable]") Pred>requires [indirectly_movable](alg.req.ind.move#concept:indirectly_movable "24.3.7.2 Concept indirectly_­movable [alg.req.ind.move]")void move_if(I first, S last, O out, Pred pred) { ranges::copy_if(move_iterator{std::move(first)}, move_sentinel{last}, std::move(out), pred);} — *end example*] [🔗](#lib:move_sentinel) namespace std {template<[semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]") S>class move_sentinel {public:constexpr move_sentinel(); constexpr explicit move_sentinel(S s); templaterequires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")constexpr move_sentinel(const move_sentinel& s); templaterequires [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]")constexpr move_sentinel& operator=(const move_sentinel& s); constexpr S base() const; private: S last; // *exposition only*};} #### [24.5.4.11](#move.sent.ops) Operations [[move.sent.ops]](move.sent.ops) [🔗](#lib:move_sentinel,constructor) `constexpr move_sentinel(); ` [1](#move.sent.ops-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5354) *Effects*: Value-initializes last[.](#move.sent.ops-1.sentence-1) If is_trivially_default_constructible_v is true, then this constructor is a constexpr constructor[.](#move.sent.ops-1.sentence-2) [🔗](#lib:move_sentinel,constructor_) `constexpr explicit move_sentinel(S s); ` [2](#move.sent.ops-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5367) *Effects*: Initializes last with std​::​move(s)[.](#move.sent.ops-2.sentence-1) [🔗](#lib:move_sentinel,constructor__) `template requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]") constexpr move_sentinel(const move_sentinel& s); ` [3](#move.sent.ops-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5380) *Effects*: Initializes last with s.last[.](#move.sent.ops-3.sentence-1) [🔗](#lib:operator=,move_sentinel) `template requires [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_­from [concept.assignable]") constexpr move_sentinel& operator=(const move_sentinel& s); ` [4](#move.sent.ops-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5394) *Effects*: Equivalent to: last = s.last; return *this; [🔗](#lib:base,move_sentinel) `constexpr S base() const; ` [5](#move.sent.ops-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5405) *Returns*: last[.](#move.sent.ops-5.sentence-1)