std::swap_ranges
来自cppreference.com
| 在标头 <algorithm> 定义
|
||
| |
(1) | (C++20 起为 constexpr) |
| |
(2) | (C++17 起) |
1) 在范围
[first1, last1) 和从 first2 开始的包含 std::distance(first1, last1) 个元素的另一范围间交换元素。2) 同 (1),但按照
policy 执行。 此重载只有在满足以下所有条件时才会参与重载决议:
|
|
(C++20 前) |
|
|
(C++20 起) |
如果满足以下任意条件,那么行为未定义:
- 两个范围有重叠。
- 两个范围中存在一对对应的迭代器
iter1和iter2,使得*iter1与*iter2不可交换 (Swappable) 。
参数
| first1, last1 | - | 要交换的第一个元素范围的迭代器对 |
| first2 | - | 要交换的第二个元素范围的起始 |
| policy | - | 所用的执行策略 |
| 类型要求 | ||
-ForwardIt1, ForwardIt2 必须满足老式向前迭代器 (LegacyForwardIterator) 。
| ||
返回值
指向从 first2 开始的范围中被交换的最末元素后一元素的迭代器。
复杂度
交换 std::distance(first1, last1) 次。
异常
拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:
- 如果作为算法一部分调用的函数的执行抛出异常,且
ExecutionPolicy是标准策略之一,那么调用 std::terminate。对于任何其他ExecutionPolicy,行为由实现定义。 - 如果算法无法分配内存,那么抛出 std::bad_alloc。
注解
实现(例如 MSVC STL )可能在迭代器类型满足老式连续迭代器 (LegacyContiguousIterator) ,并且交换其值类型不调用非平凡的特殊成员函数或 ADL 所找到的 swap 时启用向量化。
可能的实现
template<class ForwardIt1, class ForwardIt2>
constexpr //< C++20 起
ForwardIt2 swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2)
{
for (; first1 != last1; ++first1, ++first2)
std::iter_swap(first1, first2);
return first2;
}
|
示例
演示来自不同容器的子范围交换。
运行此代码
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
auto print = [](auto comment, auto const& seq)
{
std::cout << comment;
for (const auto& e : seq)
std::cout << e << ' ';
std::cout << '\n';
};
int main()
{
std::vector<char> v{'a', 'b', 'c', 'd', 'e'};
std::list<char> l{'1', '2', '3', '4', '5'};
print("swap_ranges 之前:\n" "v: ", v);
print("l: ", l);
std::swap_ranges(v.begin(), v.begin() + 3, l.begin());
print("swap_ranges 之后:\n" "v: ", v);
print("l: ", l);
}
输出:
swap_ranges 之前:
v: a b c d e
l: 1 2 3 4 5
swap_ranges 之后:
v: 1 2 3 d e
l: a b c 4 5
