# std::move_iterator

< cpp‎ | iterator

定义于头文件 `<iterator>` |  |
template< class Iter > class move_iterator; |  | (C++11 起)

`std::move_iterator` 是准确表现为底层迭代器（必须至少是一个老式输入迭代器 (LegacyInputIterator) 或实现 `input_iterator` (C++20 起)）的迭代器适配器，除了解引用会将底层迭代器返回的值转换为右值。若此迭代器用作输入迭代器，则效果是值被移动，而非复制。

### 成员类型

成员类型 | 定义
`iterator_type` | `Iter`
`iterator_category` |
std::iterator_traits<Iter>::iterator_category | (C++20 前)
若 std::iterator_traits<Iter>::iterator_category 合法且代表类型： 若 std::iterator_traits<Iter>::iterator_category 实现 std::derived_from<std::random_access_iterator_tag> 则 `iterator_category` 为 std::random_access_iterator_tag 。 否则成员 `iterator_category` 与 std::iterator_traits<Iter>::iterator_category 为同一类型。 否则无成员 `iterator_category` 。 | (C++20 起)
`iterator_concept`(C++20) | std::input_iterator_tag
`value_type` |
std::iterator_traits<Iter>::value_type | (C++20 前)
std::iter_value_t<Iter> | (C++20 起)
`difference_type` |
std::iterator_traits<Iter>::difference_type | (C++20 前)
std::iter_difference_t<Iter> | (C++20 起)
`pointer` | `Iter`
`reference` |
若 `std::iterator_traits<Iter>::reference` 为引用，则为同一类型的右值引用版本。否则（例如若包装的迭代器以值返回）为不更改的 `std::iterator_traits<Iter>::reference` | (C++20 前)
std::iter_rvalue_reference_t<Iter> | (C++20 起)

### 成员函数

(构造函数) (C++11) | 构造新的迭代器适配器 (公开成员函数)
operator= (C++11) | 赋值另一迭代器适配器 (公开成员函数)
base (C++11) | 访问底层迭代器 (公开成员函数)
operator*operator-> (C++11)(C++11)(C++20 中弃用) | 访问被指向的元素 (公开成员函数)
operator[] (C++11) | 按索引访问元素 (公开成员函数)
operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator- (C++11) | 推进或回退迭代器 (公开成员函数)

### 成员对象

成员名称 | 定义
`current` (私有成员对象) | `base()` 所复制或移动 (C++20 起)的底层迭代器，名称仅用于阐释

### 非成员函数

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) | 转型解引用底层迭代器的结果为其所关联的右值引用类型 (函数)
iter_swap (C++20) | 交换二个底层迭代器所指向的对象 (函数模板)
make_move_iterator (C++11) | 创建拥有从实参推出的类型的 std::move_iterator (函数模板)

### 示例

    #include <iostream>
    #include <iomanip>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    #include <numeric>
    #include <string>

    int main()
    {
        std::vector<std::string> v{"this", "_", "is", "_", "an", "_", "example"};

        auto print_v = [&](auto const rem) {
            std::cout << rem;
            for (const auto& s : v)
                std::cout << std::quoted(s) << ' ';
            std::cout << '\n';
        };

        print_v("Old contents of the vector: ");

        std::string concat = std::accumulate(std::make_move_iterator(v.begin()),
                                             std::make_move_iterator(v.end()),
                                             std::string());

        /* 使用 std::move_iterator 的替代方式可能是：
        using moviter_t = std::move_iterator<std::vector<std::string>::iterator>;
        std::string concat = std::accumulate(moviter_t(v.begin()),
                                             moviter_t(v.end()),
                                             std::string()); */

        print_v("New contents of the vector: ");

        std::cout << "Concatenated as string: " << quoted(concat) << '\n';
    }

可能的输出：

    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` 能返回悬垂引用 | 替而返回对象
P2259R1 | C++20 | 成员 `iterator_category` 始终有定义 | 仅若 std::iterator_traits<Iter>::iterator_category 存在才定义

### 参阅

make_move_iterator (C++11) | 创建拥有从实参推出的类型的 std::move_iterator (函数模板)
move_sentinel (C++20) | 用于 std::move_iterator 的哨位适配器 (类模板)