std::move_iterator

来自cppreference.com
< cpp‎ | iterator
 
 
迭代器库
迭代器概念
迭代器原语
算法概念与工具
间接可调用概念
常用算法要求
(C++20)
(C++20)
(C++20)
工具
(C++20)
迭代器适配器
范围访问
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
 
在标头 <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 合法且代表类型:

否则,没有 iterator_category 成员。

(C++20 起)
iterator_concept
(C++20 起)

std::input_iterator_tag

(C++23 前)
(C++23 起)
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 起)

数据成员

名称 定义
current base() 复制或移动 (C++20 起)的底层迭代器
(仅用于阐述的成员对象*)

成员函数

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

非成员函数

(C++11)(C++11)(C++20 中移除)(C++11)(C++11)(C++11)(C++11)(C++20)
比较底层迭代器
(函数模板)
比较底层迭代器与底层哨位
(函数模板)
(C++11)
令迭代器前进
(函数模板)
(C++11)
计算两个迭代器适配器间的距离
(函数模板)
计算底层迭代器与底层哨位间的距离
(函数模板)
(C++20)
将解引用底层迭代器的结果转换为其关联的右值引用类型
(函数)
(C++20)
交换两个底层迭代器所指向的对象
(函数模板)
创建拥有从实参推出的类型的 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 特化,当底层迭代器不满足 sized_sentinel_for 时,防止 move_iterator 的特化满足这个概念。

注解

功能特性测试 标准 功能特性
__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("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;
    }
 
    // 从 C++17 起引入了类模板实参推导,可以直接使用 std::move_iterator 的构造函数:
    // std::string concat = std::accumulate(std::move_iterator(v.begin()),
    //                                      std::move_iterator(v.end()),
    //                                      std::string());
 
    print("vector 的新内容:", v);
    print("拼接成字符串:", std::ranges::single_view(concat));
}

可能的输出:

vector 的旧内容:"this" "_" "is" "_" "an" "_" "example"
vector 的新内容:"" "" "" "" "" "" ""
拼接成字符串:"this_is_an_example"

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 2106 C++11 解引用底层迭代器返回纯右值时解引用 move_iterator 会返回悬垂引用 改为返回对象
LWG 3736 C++20 move_iterator 缺失了 disable_sized_sentinel_for 特化 已添加
P2259R1 C++20 std::iterator_traits<Iter>::iterator_category
未定义时也会定义成员 iterator_category
不会定义

参阅

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