std::ranges::swap
来自cppreference.com
| 在标头 <concepts> 定义
|
||
| |
(C++20 起) (定制点对象) |
|
| 调用签名 |
||
| |
(C++20 起) | |
交换 t 和 u 所引用的值。
ranges::swap(t, u) 表达式等价于:
(void)swap(t, u),如果t或u具有类或枚举类型,并且在命名空间std::ranges中,外加候选template<class T> void swap(T&, T&) = delete;进行重载决议时该表达式合法。- 如果重载决议所选择的函数没有交换
t和u所引用的值,那么程序非良构;不要求诊断。
- 如果重载决议所选择的函数没有交换
- 否则是
(void)ranges::swap_ranges(t, u),如果t和u是长度相等(但元素类型可能不同)的数组左值,且ranges::swap(*t, *u)是合法表达式,但noexcept(ranges::swap(t), ranges::swap(u))等于noexcept(ranges::swap(*t, *u)); - 否则是一个交换
t和u所引用的值的表达式,如果它们都是具有相同类型V的左值,而V实现std::move_constructible<V>和std::assignable_from<V&, V>。- 对该表达式应用
noexcept运算符的结果等于std::is_nothrow_move_constructible_v<V> && std::is_nothrow_move_assignable_v<V>。 - 该表达式在满足以下所有条件时是常量表达式:
V是字面类型 (LiteralType)t = std::move(u))和u = std::move(t)都是常量子表达式- 以下声明中的初始化式的完整表达式都是常量子表达式:
V v1(std::move(t));V v2(std::move(u));
- 对该表达式应用
- 否则,
ranges::swap(t, u)非良构,这能在ranges::swap(t, u)出现于模板实例化的立即语境时导致代换失败。
定制点对象
名字 ranges::swap 代表一个定制点对象,它是某个字面 semiregular 类类型的 const 函数对象。 细节参见定制点对象 (CustomizationPointObject) 。
示例
运行此代码
#include <array>
#include <concepts>
#include <iostream>
#include <ranges>
#include <string_view>
#include <vector>
void print(std::string_view name,
std::ranges::common_range auto const& p,
std::ranges::common_range auto const& q)
{
std::cout << name << "1{ ";
for (auto const& i : p)
std::cout << i << ' ';
std::cout << "}," << name << "2{ ";
for (auto const& i : q)
std::cout << i << ' ';
std::cout << "}\n";
}
void print(std::string_view name, int p, int q)
{
std::cout << name << "1 = " << p << "," << name << "2 = " << q << '\n';
}
struct IntLike
{
int v;
};
void swap(IntLike& lhs, int& rhs)
{
std::swap(lhs.v, rhs);
}
void swap(int& lhs, IntLike& rhs)
{
std::swap(lhs, rhs.v);
}
std::ostream& operator<<(std::ostream& out, IntLike i)
{
return out << i.v;
}
int main()
{
std::vector a1{10, 11, 12}, a2{13, 14};
std::ranges::swap(a1, a2);
print("a", a1, a2);
std::array b1{15, 16, 17}, b2{18, 19, 20};
std::ranges::swap(b1, b2);
print("b", b1, b2);
// std::array c1{1, 2, 3}; std::array c2{4, 5};
// std::ranges::swap(c1, c2); // 错误:ADL 没有找到 swap
int d1[]{21, 22, 23}, d2[]{24, 25, 26};
std::ranges::swap(d1, d2);
print("d", d1, d2);
// int e1[]{1, 2, 3}, e2[]{4, 5};
// std::ranges::swap(e1, e2); // 错误:长度不匹配
// char f1[]{1, 2, 3};
// int f2[]{4, 5, 6};
// std::ranges::swap(f1, f2); // 错误:ADL 没有找到 swap(*f1, *f2)
IntLike g1[]{1, 2, 3};
int g2[]{4, 5, 6};
std::ranges::swap(g1, g2); // 支持异质交换
print("g", g1, g2);
int h1{27}, h2{28};
std::ranges::swap(h1, h2);
print("h", h1, h2);
}
输出:
a1{ 13 14 },a2{ 10 11 12 }
b1{ 18 19 20 },b2{ 15 16 17 }
d1{ 24 25 26 },d2{ 21 22 23 }
g1{ 4 5 6 },g2{ 1 2 3 }
h1 = 28,h2 = 27
参阅
(C++20) |
指定一个类型能进行交换,或两个类型能彼此交换 (概念) |
| 交换两个对象的值 (函数模板) |