std::move_iterator
来自 cppreference.cn
定义于头文件 <iterator> |
||
template< class Iter > class move_iterator; |
(自 C++11 起) | |
std::move_iterator
是一个迭代器适配器,其行为与底层迭代器完全相同(底层迭代器必须至少是 LegacyInputIterator 或模型 input_iterator
(自 C++20 起),或更强的迭代器概念(自 C++23 起)),但解引用会把底层迭代器返回的值转换成右值。如果此迭代器被用作输入迭代器,其效果是从值移动,而不是从值复制。
内容 |
[编辑] 嵌套类型
|
(直到 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 (函数模板) |
[编辑] 辅助模板
template< class Iterator1, class Iterator2 > requires (!std::sized_sentinel_for<Iterator1, Iterator2>) |
(自 C++20 起) | |
std::disable_sized_sentinel_for
的此部分特化阻止 move_iterator
的特化在它们的底层迭代器不满足概念 sized_sentinel_for
时满足它。
[编辑] 注解
特性测试 宏 | 值 | Std | 特性 |
---|---|---|---|
__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 可能返回悬垂引用如果解引用底层迭代器返回一个纯右值 |
返回 对象代替 |
LWG 3736 | C++20 | move_iterator 遗漏 disable_sized_sentinel_for 特化 |
已添加 |
P2259R1 | C++20 | 即使 std::iterator_traits<Iter>::iterator_category 未定义,成员 iterator_category 仍被定义std::iterator_traits<Iter>::iterator_category is not defined |
iterator_category 在此情况下为未定义 |
[编辑] 参见
(C++11) |
创建从实参推导类型的 std::move_iterator (函数模板) |
(C++20) |
std::move_iterator 的哨位适配器 (类模板) |