std::move_iterator
来自cppreference.com
<tbody>
</tbody>
| 在标头 <iterator> 定义
|
||
template< class Iter > class move_iterator; |
(C++11 起) | |
std::move_iterator 是一种迭代器适配器,表现与它的底层迭代器(必须至少是一个老式输入迭代器 (LegacyInputIterator) 或实现 input_iterator (C++20 起))严格相同,但解引用会将底层迭代器返回的值转换为右值。如果此迭代器用作输入迭代器,那么效果是值被移动,而非复制。
嵌套类型
|
(C++20 前) | ||||||||||||||||||||
|
(C++20 起) |
数据成员
| 成员 | 描述 |
Iter current
|
底层迭代器 (仅用于阐述的成员对象*) |
成员函数
构造新的 move_iterator (公开成员函数) | |
赋值另一 move_iterator (公开成员函数) | |
| 访问底层迭代器 (公开成员函数) | |
| 访问被指向的元素 (公开成员函数) | |
| 按索引访问元素 (公开成员函数) | |
推进或回退 move_iterator (公开成员函数) |
非成员函数
(C++11)(C++11)(C++20 移除)(C++11)(C++11)(C++11)(C++11)(C++20) |
比较底层迭代器 (函数模板) |
| 比较底层迭代器与底层哨位 (函数模板) | |
(C++11) |
令迭代器前进 (函数模板) |
(C++11) |
计算两个迭代器适配器间的距离 (函数模板) |
| 计算底层迭代器与底层哨位间的距离 (函数模板) | |
(C++20) |
将解引用底层迭代器的结果转换为其关联的右值引用类型 (函数) |
(C++20) |
交换两个底层迭代器所指向的对象 (函数模板) |
(C++11) |
创建拥有从实参推出的类型的 std::move_iterator (函数模板) |
辅助模板
<tbody> </tbody> 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}; // 将 *begin 的内容移动到 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
|
不会定义 |
参阅
(C++11) |
创建拥有从实参推出的类型的 std::move_iterator (函数模板) |
(C++20) |
std::move_iterator 的哨位适配器 (类模板) |