您的位置:首页 > 房产 > 建筑 > 乐清市网站建设公司_河北邯郸疫情最新情况 最新消息_优化大师下载安装app_职业技能培训中心

乐清市网站建设公司_河北邯郸疫情最新情况 最新消息_优化大师下载安装app_职业技能培训中心

2024/12/23 9:11:46 来源:https://blog.csdn.net/qq_55125921/article/details/144335473  浏览:    关键词:乐清市网站建设公司_河北邯郸疫情最新情况 最新消息_优化大师下载安装app_职业技能培训中心
乐清市网站建设公司_河北邯郸疫情最新情况 最新消息_优化大师下载安装app_职业技能培训中心

文章目录

      • 1. **概述**
      • 2. **成员类型和成员对象**
      • 3. **构造函数**
      • 4. **成员函数**
      • 5. **非成员函数**
        • 5.1 **`make_pair`**
        • 5.2 **比较运算符**
        • 5.3 **`std::swap`**
        • 5.4 **`std::get`**
      • 6. **辅助类**
        • 6.1 **`std::tuple_size` 和 `std::tuple_element`**
        • 6.2 **`std::common_type` 和 `std::basic_common_reference`**
        • 6.3 **`std::formatter`**
      • 7. **析构函数**
      • 8. **示例代码**
      • 9. **总结**
      • 1. **`std::pair` 与 `std::tuple` 的集成**
        • 示例:将 `std::pair` 转换为 `std::tuple`
        • 输出:
        • 示例:将 `std::tuple` 转换为 `std::pair`
        • 输出:
      • 2. **`std::pair` 与 `std::map` 的集成**
        • 示例:使用 `std::pair` 插入和访问 `std::map` 中的元素
        • 输出:
        • 解释:
      • 3. **`std::pair` 与 `std::set` 的集成**
        • 示例:使用 `std::pair` 存储多个属性的唯一组合
        • 输出:
        • 解释:
        • 自定义排序规则
        • 输出:
        • 解释:
      • 4. **总结**

std::pair 是 C++ 标准库中的一个类模板,用于将两个异构对象组合成一个单元。它在头文件 <utility> 中定义,并且是 std::tuple 的一个特例,专门用于处理两个元素的情况。 std::pair 在许多情况下非常有用,例如作为关联容器(如 std::map)的键值对,或者当需要返回多个值时。

1. 概述

std::pair 的定义如下:

template<class T1, class T2>
struct pair {// 成员类型typedef T1 first_type;typedef T2 second_type;// 成员对象T1 first;T2 second;// 构造函数constexpr pair() : first(T1()), second(T2()) {}constexpr pair(const T1& x, const T2& y) : first(x), second(y) {}constexpr pair(T1&& x, T2&& y) : first(std::move(x)), second(std::move(y)) {}template<class U1, class U2>constexpr pair(U1&& x, U2&& y) : first(std::forward<U1>(x)), second(std::forward<U2>(y)) {}// 其他构造函数...// 成员函数constexpr void swap(pair& other) noexcept(/* see below */);// ...
};

2. 成员类型和成员对象

  • first_type:第一个元素的类型,即 T1
  • second_type:第二个元素的类型,即 T2
  • first:存储第一个元素的成员变量。
  • second:存储第二个元素的成员变量。

3. 构造函数

std::pair 提供了多种构造方式:

  • 默认构造:使用默认构造函数初始化 firstsecond
  • 复制构造:从两个已有的对象构造 pair
  • 移动构造:从两个右值引用的对象构造 pair
  • 模板构造:允许从不同类型的对象构造 pair,支持隐式转换。

4. 成员函数

  • operator=:赋值操作符,用于将另一个 pair 的内容赋值给当前 pair
  • swap:交换两个 pair 的内容。自 C++11 起,swap 函数被标记为 noexcept,如果 T1T2swap 操作也是 noexcept 的话。

5. 非成员函数

5.1 make_pair

make_pair 是一个方便的函数模板,用于创建 std::pair 对象。它会根据传入的参数类型自动推导出 pair 的类型。

template<class T1, class T2>
constexpr pair<T1, T2> make_pair(T1 t, T2 u);

示例:

#include <utility>int main() {auto p = std::make_pair(42, "Hello");std::cout << p.first << ", " << p.second << '\n';
}

输出:

42, Hello
5.2 比较运算符

std::pair 支持按字典顺序进行比较。C++20 之前,提供了以下比较运算符:

  • operator==:检查两个 pair 是否相等。
  • operator!=:检查两个 pair 是否不相等。
  • operator<:按字典顺序比较两个 pair
  • operator<=:按字典顺序检查一个 pair 是否小于或等于另一个 pair
  • operator>:按字典顺序检查一个 pair 是否大于另一个 pair
  • operator>=:按字典顺序检查一个 pair 是否大于或等于另一个 pair

C++20 引入了三路比较运算符 operator<=>,它可以在支持三路比较的类型上使用。

template<class T1, class T2>
constexpr std::strong_ordering operator<=>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
5.3 std::swap

std::swap 专门化用于交换两个 pair 的内容。自 C++11 起,std::swap 可以更高效地交换 pair 的元素。

template<class T1, class T2>
void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(/* see below */);
5.4 std::get

std::get 是 C++11 引入的一个模板函数,用于访问 pair 的元素。它可以与 std::tuple 一起使用,但在 pair 上也可以工作。

template<std::size_t I, class T1, class T2>
constexpr typename std::tuple_element<I, pair<T1, T2>>::type& get(pair<T1, T2>& p);template<std::size_t I, class T1, class T2>
constexpr typename std::tuple_element<I, pair<T1, T2>>::type&& get(pair<T1, T2>&& p);template<std::size_t I, class T1, class T2>
constexpr const typename std::tuple_element<I, pair<T1, T2>>::type& get(const pair<T1, T2>& p);

示例:

#include <utility>
#include <iostream>int main() {std::pair<int, double> p(42, 3.14);std::cout << std::get<0>(p) << ", " << std::get<1>(p) << '\n';
}

输出:

42, 3.14

6. 辅助类

6.1 std::tuple_sizestd::tuple_element

std::tuple_sizestd::tuple_element 是 C++11 引入的模板类,用于获取 pair 的大小和元素类型。

  • std::tuple_size<std::pair<T1, T2>>:表示 pair 的大小为 2。
  • std::tuple_element<0, std::pair<T1, T2>>:表示 pair 的第一个元素类型为 T1
  • std::tuple_element<1, std::pair<T1, T2>>:表示 pair 的第二个元素类型为 T2
6.2 std::common_typestd::basic_common_reference

C++23 引入了 std::common_typestd::basic_common_reference 的特化,用于确定两个 pair 的公共类型和公共引用类型。

6.3 std::formatter

C++23 引入了 std::formatter 的特化,用于支持 std::pair 的格式化输出。这使得 std::pair 可以与 std::format 等函数一起使用。

7. 析构函数

如果 T1T2 都不可能是具有非平凡析构函数的 cv 限定类类型或数组,则 pair 的析构函数是平凡的。这意味着在这种情况下,pair 的析构不会引入额外的开销。

8. 示例代码

以下是一个完整的示例,展示了 std::pair 的基本用法:

#include <iostream>
#include <utility>
#include <string>int main() {// 创建一个 pairstd::pair<int, std::string> p(42, "Hello");// 访问 pair 的元素std::cout << "First: " << p.first << ", Second: " << p.second << '\n';// 使用 make_pair 创建 pairauto p2 = std::make_pair(3.14, 'A');std::cout << "First: " << p2.first << ", Second: " << p2.second << '\n';// 比较两个 pairstd::pair<int, int> p3(1, 2);std::pair<int, int> p4(1, 3);if (p3 < p4) {std::cout << "p3 is less than p4\n";}// 交换两个 pairp3.swap(p4);std::cout << "After swap: p3 = (" << p3.first << ", " << p3.second << "), p4 = (" << p4.first << ", " << p4.second << ")\n";// 使用 std::get 访问元素std::pair<double, char> p5(3.14, 'B');std::cout << "First: " << std::get<0>(p5) << ", Second: " << std::get<1>(p5) << '\n';return 0;
}

9. 总结

std::pair 是 C++ 标准库中一个非常有用的工具,特别适用于需要将两个不同类型的数据组合在一起的情况。它提供了丰富的构造函数、成员函数和非成员函数,使得操作 pair 变得非常灵活和方便。std::pair 还与其他标准库功能(如 std::tuplestd::mapstd::set 等)无缝集成,进一步扩展了其应用场景。

如果你有更多具体的问题或需要进一步的帮助,请随时提问!

std::pair 是 C++ 标准库中一个非常灵活的工具,它可以与其他标准库功能无缝集成,从而扩展其应用场景。下面我将分别介绍 std::pair 如何与 std::tuplestd::mapstd::set 集成,并提供具体的例子。

1. std::pairstd::tuple 的集成

std::pairstd::tuple 的特例,std::tuple 可以看作是 std::pair 的泛化版本,允许存储任意数量的元素。因此,std::pair 可以很容易地转换为 std::tuple,反之亦然。

示例:将 std::pair 转换为 std::tuple
#include <iostream>
#include <utility> // for std::pair
#include <tuple>   // for std::tupleint main() {// 创建一个 std::pairstd::pair<int, double> p(42, 3.14);// 将 std::pair 转换为 std::tupleauto t = std::tuple(p.first, p.second);// 访问 tuple 中的元素std::cout << "Tuple contains: " << std::get<0>(t) << ", " << std::get<1>(t) << '\n';return 0;
}
输出:
Tuple contains: 42, 3.14
示例:将 std::tuple 转换为 std::pair
#include <iostream>
#include <utility> // for std::pair
#include <tuple>   // for std::tupleint main() {// 创建一个 std::tuplestd::tuple<int, double> t(42, 3.14);// 将 std::tuple 转换为 std::pairauto p = std::make_pair(std::get<0>(t), std::get<1>(t));// 访问 pair 中的元素std::cout << "Pair contains: " << p.first << ", " << p.second << '\n';return 0;
}
输出:
Pair contains: 42, 3.14

2. std::pairstd::map 的集成

std::map 是一个关联容器,用于存储键值对。std::pair 经常用于表示这些键值对。实际上,std::map 的插入操作返回的是一个 std::pair,其中包含插入的迭代器和一个布尔值,表示插入是否成功。

示例:使用 std::pair 插入和访问 std::map 中的元素
#include <iostream>
#include <map>
#include <utility> // for std::pairint main() {// 创建一个 std::mapstd::map<std::string, int> student_grades;// 使用 std::pair 插入元素student_grades.insert(std::make_pair("Alice", 95));student_grades.insert(std::make_pair("Bob", 88));student_grades.insert(std::make_pair("Charlie", 92));// 访问 map 中的元素for (const auto& [name, grade] : student_grades) {std::cout << name << ": " << grade << '\n';}// 插入并检查是否成功auto result = student_grades.insert(std::make_pair("Alice", 100));if (!result.second) {std::cout << "Insertion failed: Key 'Alice' already exists.\n";}return 0;
}
输出:
Alice: 95
Bob: 88
Charlie: 92
Insertion failed: Key 'Alice' already exists.
解释:
  • student_grades.insert(std::make_pair("Alice", 95)) 插入了一个键值对,其中 "Alice" 是键,95 是值。
  • auto result = student_grades.insert(std::make_pair("Alice", 100)) 返回一个 std::pair,其中第一个元素是插入的迭代器,第二个元素是一个布尔值,表示插入是否成功。由于 "Alice" 已经存在于 map 中,插入失败,result.secondfalse

3. std::pairstd::set 的集成

std::set 是一个有序集合,存储唯一的元素。虽然 std::set 通常用于存储单个类型的元素,但它也可以存储 std::pair,并且可以基于 pair 的两个元素进行排序。

示例:使用 std::pair 存储多个属性的唯一组合
#include <iostream>
#include <set>
#include <utility> // for std::pairint main() {// 创建一个 std::set,存储 std::pairstd::set<std::pair<int, std::string>> unique_pairs;// 插入一些 pairunique_pairs.insert(std::make_pair(1, "Apple"));unique_pairs.insert(std::make_pair(2, "Banana"));unique_pairs.insert(std::make_pair(3, "Cherry"));// 插入重复的 pair(不会插入)unique_pairs.insert(std::make_pair(1, "Apple"));// 遍历 set 并输出元素for (const auto& [number, fruit] : unique_pairs) {std::cout << number << ": " << fruit << '\n';}return 0;
}
输出:
1: Apple
2: Banana
3: Cherry
解释:
  • std::set 会自动根据 pair 的字典顺序进行排序。首先比较 first 元素,如果相同则比较 second 元素。
  • 由于 std::set 只存储唯一的元素,尝试插入相同的 pair(如 std::make_pair(1, "Apple"))不会改变集合的内容。
自定义排序规则

你还可以通过提供自定义的比较函数来控制 std::setstd::pair 的排序方式。例如,如果你想只根据 pairsecond 元素进行排序:

#include <iostream>
#include <set>
#include <utility> // for std::pair// 自定义比较函数,只比较 second 元素
struct CompareSecond {bool operator()(const std::pair<int, std::string>& a, const std::pair<int, std::string>& b) const {return a.second < b.second;}
};int main() {// 创建一个 std::set,使用自定义比较函数std::set<std::pair<int, std::string>, CompareSecond> unique_pairs;// 插入一些 pairunique_pairs.insert(std::make_pair(1, "Apple"));unique_pairs.insert(std::make_pair(2, "Banana"));unique_pairs.insert(std::make_pair(3, "Cherry"));// 遍历 set 并输出元素for (const auto& [number, fruit] : unique_pairs) {std::cout << number << ": " << fruit << '\n';}return 0;
}
输出:
1: Apple
2: Banana
3: Cherry
解释:
  • 在这个例子中,std::set 根据 pairsecond 元素(即字符串)进行排序,而不是默认的字典顺序。

4. 总结

  • std::pairstd::tuplestd::pairstd::tuple 的特例,两者可以轻松互转,适用于需要处理两个元素的情况。
  • std::pairstd::mapstd::map 内部使用 std::pair 来存储键值对,insert 操作返回的也是一个 std::pair,方便检查插入是否成功。
  • std::pairstd::setstd::set 可以存储 std::pair,并且可以根据 pair 的两个元素进行排序,甚至可以通过自定义比较函数来控制排序规则。

通过这些集成,std::pair 成为了 C++ 标准库中非常强大且灵活的工具,适用于多种场景。如果你有更多具体的问题或需要进一步的帮助,请随时提问!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com