Spec-Zone.ru › C++

std::move_iterator

Определён в заголовке <iterator>
template< class Iter >
class move_iterator;
(начиная с C++11)

std::move_iterator — это адаптер итератора, который ведёт себя точно так же, как базовый итератор (который должен быть как минимум LegacyInputIterator или моделировать input_iterator(начиная с C++20) либо более строгую концепцию итератора(начиная с C++23)), за исключением того, что разыменование преобразует значение, возвращаемое базовым итератором, в rvalue. Если этот итератор используется как входной итератор, значения перемещаются, а не копируются.

Вложенные типы

Тип Определение
iterator_type Iter
iterator_category std::iterator_traits<Iter>::iterator_category
value_type std::iterator_traits<Iter>::value_type
difference_type std::iterator_traits<Iter>::difference_type
pointer Iter
reference
  • версия с rvalue-ссылкой для std::iterator_traits<Iter>::reference, если std::iterator_traits<Iter>::reference является ссылочным типом
  • std::iterator_traits<Iter>::reference в противном случае
(до C++20)
Тип Определение
iterator_type Iter
iterator_category
(присутствует при определённых условиях)
  • не определён, если std::iterator_traits<Iter>::iterator_category некорректен или не обозначает тип
  • std::random_access_iterator_tag, если std::iterator_traits<Iter>::iterator_category моделирует std::derived_from<std::random_access_iterator_tag>
  • std::iterator_traits<Iter>::iterator_category в противном случае
iterator_concept

std::input_iterator_tag

(до C++23)
  • std::random_access_iterator_tag, если Iter моделирует std::random_access_iterator
  • std::bidirectional_iterator_tag, если Iter моделирует только std::bidirectional_iterator
  • std::forward_iterator_tag, если Iter моделирует только std::forward_iterator
  • std::input_iterator_tag в противном случае
(начиная с C++23)
value_type std::iter_value_t<Iter>
difference_type std::iter_difference_t<Iter>
pointer Iter
reference std::iter_rvalue_reference_t<Iter>
(начиная с C++20)

Члены-данные

Член Описание
Iter current базовый итератор
(объект-член, используемый только для описания*)

Функции-члены

(constructor)
создаёт новый move_iterator
(открытая функция-член)
operator=
присваивает другой move_iterator
(открытая функция-член)
base
обращается к базовому итератору
(открытая функция-член)
operator*operator->
обращается к элементу, на который указывает итератор
(открытая функция-член)
operator[]
обращается к элементу по индексу
(открытая функция-член)
operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator-
перемещает move_iterator вперёд или назад
(открытая функция-член)

Функции, не являющиеся членами

operator==operator!=operator<operator<=operator>operator>=operator<=>
(C++11)(C++11)(удалён в C++20)(C++11)(C++11)(C++11)(C++11)(C++20)
сравнивает базовые итераторы
(шаблон функции)
operator==(std::move_sentinel)
(C++20)
сравнивает базовый итератор и базовый сентинел
(шаблон функции)
operator+
(C++11)
перемещает итератор вперёд
(шаблон функции)
operator-
(C++11)
вычисляет расстояние между двумя адаптерами итераторов
(шаблон функции)
operator-(std::move_sentinel)
(C++20)
вычисляет расстояние между базовым итератором и базовым сентинелом
(шаблон функции)
iter_move
(C++20)
приводит результат разыменования базового итератора к соответствующему типу rvalue-ссылки
(функция)
iter_swap
(C++20)
меняет местами объекты, на которые указывают два базовых итератора
(шаблон функции)
make_move_iterator
(C++11)
создаёт std::move_iterator с типом, выведенным из аргумента
(шаблон функции)

Вспомогательные шаблоны

template< class Iterator1, class Iterator2 >
    requires (!std::sized_sentinel_for<Iterator1, Iterator2>)
constexpr bool disable_sized_sentinel_for
    <std::move_iterator<Iterator1>, std::move_iterator<Iterator2>> = true;
(начиная с C++20)

Эта частичная специализация std::disable_sized_sentinel_for не позволяет специализациям move_iterator удовлетворять концепции sized_sentinel_for, если их базовые итераторы не удовлетворяют этой концепции.

Примечания

Макрос проверки поддержки Значение Стандарт Функция
__cpp_lib_move_iterator_concept 202207L (C++23) Сделать std::move_iterator<T*> итератором произвольного доступа

Пример

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <ranges>
#include <string>
#include <string_view>
#include <vector>

void print(const std::string_view rem, const auto& v)
{
    std::cout << rem;
    for (const auto& s : v)
        std::cout << std::quoted(s) << ' ';
    std::cout << '\n';
};

int main()
{
    std::vector<std::string> v{"this", "_", "is", "_", "an", "_", "example"};
    print("Old contents of the vector: ", v);
    std::string concat;
    for (auto begin = std::make_move_iterator(v.begin()),
              end = std::make_move_iterator(v.end());
         begin != end; ++begin)
    {
        std::string temp{*begin}; // moves the contents of *begin to temp
        concat += temp;
    }
    
    // Starting from C++17, which introduced class template argument deduction,
    // the constructor of std::move_iterator can be used directly:
    // std::string concat = std::accumulate(std::move_iterator(v.begin()),
    //                                      std::move_iterator(v.end()),
    //                                      std::string());
    
    print("New contents of the vector: ", v);
    print("Concatenated as string: ", std::ranges::single_view(concat));
}

Возможный вывод:

Old contents of the vector: "this" "_" "is" "_" "an" "_" "example"
New contents of the vector: "" "" "" "" "" "" ""
Concatenated as string: "this_is_an_example"

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.

DR Применяется к Опубликованное поведение Корректное поведение
LWG 2106 C++11 разыменование move_iterator могло возвращать висячую ссылку,
если разыменование базового итератора возвращало prvalue
вместо этого возвращает
объект
LWG 3736 C++20 в move_iterator отсутствовала специализация disable_sized_sentinel_for добавлена
P2259R1 C++20 член iterator_category определялся даже в случае,
если std::iterator_traits<Iter>::iterator_category не определён
iterator_category в этом случае
не определён

См. также

make_move_iterator
(C++11)
создаёт std::move_iterator с типом, выведенным из аргумента
(шаблон функции)
move_sentinel
(C++20)
адаптер сентинела для std::move_iterator
(шаблон класса)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/iterator/move_iterator

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API