std:: move_iterator
|
定义于头文件
<iterator>
|
||
|
template
<
class
Iter
>
class move_iterator ; |
(C++11 起) | |
std::move_iterator
是一种迭代器适配器,其行为与底层迭代器(必须至少满足
LegacyInputIterator
或建模
input_iterator
(C++20 起)
,或更强的迭代器概念
(C++23 起)
)完全相同,区别在于解引用操作会将底层迭代器返回的值转换为右值。若将此迭代器用作输入迭代器,效果是值会被移出而非复制。
目录 |
嵌套类型
|
(C++20 前) | ||||||||||||||||||||
|
(C++20 起) |
数据成员
| 成员 | td> 描述|
Iter
current
|
底层迭代器
( 仅用于说明的成员对象* ) |
成员函数
构造新的
move_iterator
(公开成员函数) |
|
赋值另一个
move_iterator
(公开成员函数) |
|
|
访问底层迭代器
(公开成员函数) |
|
|
访问指向的元素
(公开成员函数) |
|
|
通过索引访问元素
(公开成员函数) |
|
前进或后退
move_iterator
(公开成员函数) |
非成员函数
|
(C++11)
(C++11)
(removed in C++20)
(C++11)
(C++11)
(C++11)
(C++11)
(C++20)
|
比较底层迭代器
(函数模板) |
|
(C++20)
|
比较底层迭代器与底层哨兵
(函数模板) |
|
(C++11)
|
前进迭代器
(函数模板) |
|
(C++11)
|
计算两个迭代器适配器间的距离
(函数模板) |
|
(C++20)
|
计算底层迭代器与底层哨兵间的距离
(函数模板) |
|
(C++20)
|
将底层迭代器解引用结果转换为其关联的右值引用类型
(函数) |
|
(C++20)
|
交换两个底层迭代器所指向的对象
(函数模板) |
|
(C++11)
|
创建从参数推断类型的
std::move_iterator
(函数模板) |
辅助模板
|
template
<
class
Iterator1,
class
Iterator2
>
requires
(
!
std::
sized_sentinel_for
<
Iterator1, Iterator2
>
)
|
(自 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}; // 将 *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("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++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2106 | C++11 |
解引用
move_iterator
可能返回悬空引用
若解引用底层迭代器返回纯右值 |
改为返回
对象本身 |
| LWG 3736 | C++20 |
move_iterator
缺失
disable_sized_sentinel_for
特化
|
已添加 |
| P2259R1 | C++20 |
成员类型
iterator_category
被定义即使
std:: iterator_traits < Iter > :: iterator_category 未定义 |
此情况下
不定义
iterator_category
|
参见
|
(C++11)
|
创建从参数推断类型的
std::move_iterator
(函数模板) |
|
(C++20)
|
std::move_iterator
的哨兵适配器
(类模板) |