当前位置: 首页 > news >正文

探秘C++中的神奇组合:std--pair的魅力之旅

探秘C++中的神奇组合:std::pair的魅力之旅

  • 引言
  • std::pair简介及基本概念(An Overview and Basic Concepts of std::pair)
    • std::pair的结构及构造方法(Structure and Construction Methods of std::pair)
    • std::pair的常用成员函数(Common Member Functions of std::pair)
  • std::pair底层原理解析
    • a. 编译器角度
    • b. 内存角度
    • c. 构造和析构
    • d. 编译时优化
    • e. 内存管理
  • std::pair的实际应用案例(Practical Use Cases of std::pair)
    • 在关联容器中使用std::pair(Using std::pair in Associative Containers)
    • 用于多重返回值和函数参数(Multi-Return Values and Function Parameters)
    • 与其他容器一起使用std::pair(Using std::pair with Other Containers)
  • std::pair的高级用法(Advanced Usage of std::pair)
    • 结构化绑定(Structured Bindings, C++17)
    • 使用std::pair实现比较运算符(Using std::pair to Implement Comparison Operators)
    • 在Lambda表达式中使用std::pair(Using std::pair with Lambda Expressions)
  • std::pair的扩展:std::tuple(Extending std::pair: std::tuple)
    • std::tuple简介及使用方法(Introduction and Usage of std::tuple)
    • std::tuple与std::pair的比较(Comparing std::tuple and std::pair)
  • 常见问题及解答(Frequently Asked Questions and Answers)
    • 问题1:为什么我不能将std::pair或std::tuple的不同类型实例直接赋值给另一个?
    • 问题2:我可以将std::pair或std::tuple的成员设为const吗?
    • 问题3:我可以使用指针或引用作为std::pair或std::tuple的成员类型吗?
    • 问题4:在std::pair中,如何使用自定义类型作为成员?
    • 问题5:如何在std::pair中存储多于两个成员的数据结构?
    • 问题6:如何在容器(如std::vector、std::map等)中使用std::pair?
    • 问题7:如何在std::pair中实现自定义比较?
  • 结语

引言

在C++编程中,我们常常会遇到需要将两个相关的数据元素组合在一起的情况。为了满足这一需求,C++标准库提供了一个名为std::pair的实用工具,可以将两个数据元素组合成一个对象。std::pair不仅易于使用,而且在实际编程中有着广泛的应用。

本文将详细介绍std::pair的定义、基本概念以及实际应用,帮助读者更好地理解和掌握这个实用的C++组件。文章将从std::pair的简介及基本概念入手,介绍其构造方法、常用成员函数等;接着,我们将深入探讨std::pair在实际应用中的案例,如关联容器、多重返回值和函数参数等;然后,我们将探讨std::pair的扩展:std::tuple,对比二者的优缺点;最后,我们将回答关于std::pair的常见问题,并总结其灵活性与强大功能。

让我们一起踏上这场C++中std::pair的魅力之旅吧!


std::pair的定义和应用(Introduction: Definition and Applications of std::pair)

std::pair简介及基本概念(An Overview and Basic Concepts of std::pair)

std::pair的结构及构造方法(Structure and Construction Methods of std::pair)

std::pair是一个简单的模板类,它包含两个公开的数据成员,分别称为first和second。这两个数据成员可以是同类型或不同类型的元素。以下是std::pair的定义:

template <class T1, class T2>
struct pair {T1 first;T2 second;
};

创建一个std::pair对象有多种方法:

  1. 直接构造:使用构造函数将两个元素作为参数传递。
    std::pair<int, std::string> p1(1, "one");
  2. 使用make_pair:make_pair是一个实用函数,可以根据传入的参数自动推导出相应类型的std::pair。
    auto p2 = std::make_pair(2, "two");
  3. 使用列表初始化(C++11及以后):
    std::pair<int, std::string> p3{3, "three"};

std::pair的常用成员函数(Common Member Functions of std::pair)

虽然std::pair本身没有太多的成员函数,但其内部的数据成员可以很容易地访问和修改。除了可以直接操作first和second数据成员之外,std::pair还提供了如下成员函数:

  1. swap:交换两个std::pair对象的内容
    std::pair<int, std::string> p1(1, "one");
    std::pair<int, std::string> p2(2, "two");
    p1.swap(p2);
  2. operator==, operator!=, operator<, operator<=, operator>, operator>=:这些运算符允许我们比较两个std::pair对象。比较操作首先比较first成员,如果相等,则继续比较second成员。
    std::pair<int, std::string> p1(1, "one");
    std::pair<int, std::string> p2(2, "two");if (p1 < p2) {// do something
    }

了解了std::pair的基本概念之后,我们将在下一部分中探讨其底层原理。

std::pair底层原理解析

a. 编译器角度

std::pair是一个模板类,它定义了一个具有两个数据成员的数据结构。编译器在编译期间根据所提供的模板参数生成相应的实例化类型。对于不同的模板参数组合,编译器将为每组参数生成一个唯一的std::pair类型。这意味着对于每一种不同类型的std::pair,编译器都会生成相应的类型信息和成员函数实现。

编译器优化也在std::pair的实现中起着关键作用。例如,当使用std::make_pair()函数时,编译器会使用返回值优化(RVO)或命名返回值优化(NRVO),以避免创建临时对象并进行额外的复制操作。这使得std::pair在性能上具有很高的效率。

b. 内存角度

std::pair的内存布局非常简单,仅包含两个数据成员。这两个成员在内存中是连续存储的。std::pair的内存大小是其两个数据成员的大小之和,加上可能的内存对齐填充。通常情况下,内存对齐填充不会导致std::pair的内存占用显著增加。

在使用std::pair时,需要注意内存对齐的问题。如果成员类型具有特定的对齐要求,可能需要在数据成员之间添加填充以满足这些要求。对于大多数编译器,这会自动处理。但是,为了避免潜在的性能问题和跨平台兼容性问题,了解如何手动管理内存对齐和填充是很重要的。

c. 构造和析构

std::pair的构造和析构过程与其他简单的C++类似。当创建一个std::pair对象时,其数据成员会根据构造函数的参数进行初始化。在构造过程中,会首先调用第一个数据成员的构造函数,然后调用第二个数据成员的构造函数。析构过程则相反,首先调用第二个数据成员的析构函数,然后调用第一个数据成员的析构函数。

在实例化std::pair时,需要注意其数据成员的构造和析构顺序。确保数据成员的生命周期正确管理,以避免资源泄漏和潜在的错误。

总结一下,从编译器和内存角度来看,std::pair是一个简单且高效的数据结构。编译器负责实例化特定的std::pair类型,并使用优化策略(如RVO和NRVO)来提高性能。在内存布局上,std::pair仅包含两个连续存储的数据成员,可能还有一些内存对齐填充。构造和析构过程中,需要注意成员的生命周期和顺序。

d. 编译时优化

由于std::pair是一个模板类,许多操作都在编译时进行。这使得编译器可以在很大程度上优化std::pair的使用。例如,当使用constexpr关键字定义一个std::pair对象时,所有操作都在编译时进行,减少了运行时开销。

另外,当std::pair的成员类型为简单类型(如int、float等)时,编译器可以进一步优化生成的代码。如果操作符重载(如比较运算符)在编译时就可以确定结果,编译器会尽量进行编译时计算,提高运行时性能。

e. 内存管理

std::pair作为一个轻量级的数据结构,在内存管理方面通常不会引起问题。然而,在使用指针或引用作为std::pair成员时,需要特别注意内存管理和对象生命周期。当使用原始指针时,要确保在不再使用std::pair对象时,适当地释放内存。与智能指针(如std::shared_ptr和std::unique_ptr)结合使用,可以简化内存管理,自动处理对象的生命周期。

此外,当std::pair的成员类型是大型对象或数组时,需要考虑内存分配的性能影响。尽量避免在热代码路径上频繁创建和销毁std::pair对象。可以使用对象池、缓存等技术来减少内存分配和回收的开销。

通过了解std::pair的底层原理,我们可以在编写C++代码时更加自信地使用std::pair,了解其性能和效率。编译器和内存方面的知识有助于在需要时进行优化,并确保我们的代码具有良好的性能和跨平台兼容性。

了解了std::pair的底层原理之后,我们将在下一部分中探讨其在实际应用中的使用。

std::pair的实际应用案例(Practical Use Cases of std::pair)

在关联容器中使用std::pair(Using std::pair in Associative Containers)

关联容器(如std::map和std::unordered_map)在C++中被广泛使用。这些容器的底层实现利用了std::pair来存储键值对。例如,在使用std::map时,可以通过insert()方法插入一个std::pair对象。

std::map<int, std::string> my_map;
my_map.insert(std::pair<int, std::string>(1, "one"));
my_map.insert(std::make_pair(2, "two"));

在遍历关联容器时,迭代器会返回一个指向std::pair对象的引用。这允许我们直接访问键和值。

for (const auto& kv : my_map) {std::cout << "Key: " << kv.first << ", Value: " << kv.second << std::endl;
}

用于多重返回值和函数参数(Multi-Return Values and Function Parameters)

在某些情况下,函数需要返回多个值。std::pair是解决这类问题的一个有效方式。例如,我们可以编写一个函数,该函数返回一个点的极坐标:

std::pair<double, double> to_polar(double x, double y) {double r = std::sqrt(x * x + y * y);double theta = std::atan2(y, x);return std::make_pair(r, theta);
}

同样,我们可以使用std::pair作为函数参数,将多个相关值打包到一个参数中。

void process_data(const std::pair<std::string, int>& data) {// Process data here
}

与其他容器一起使用std::pair(Using std::pair with Other Containers)

std::pair可以与其他容器(如std::vector、std::list和std::deque)一起使用,以便将一组相关数据组织在一起。

例如,我们可以将多个人员的姓名和年龄存储在一个std::vector中:

std::vector<std::pair<std::string, int>> people;
people.push_back(std::make_pair("Alice", 30));
people.push_back(std::make_pair("Bob", 25));

至此,我们已经介绍了std::pair在实际应用中的一些用例。

std::pair的高级用法(Advanced Usage of std::pair)

结构化绑定(Structured Bindings, C++17)

C++17引入了结构化绑定,这是一种简化从std::pair和std::tuple中提取数据的方法。使用结构化绑定,我们可以直接将std::pair或std::tuple的成员分配给独立的变量。以下是一个使用结构化绑定从std::pair中提取数据的示例:

std::pair<int, std::string> my_pair(1, "one");// C++17结构化绑定
auto [num, str] = my_pair;std::cout << "Num: " << num << ", Str: " << str << std::endl;

同样,我们也可以在遍历关联容器时使用结构化绑定,简化代码:

std::map<int, std::string> my_map{{1, "one"}, {2, "two"}};for (const auto& [key, value] : my_map) {std::cout << "Key: " << key << ", Value: " << value << std::endl;
}

使用std::pair实现比较运算符(Using std::pair to Implement Comparison Operators)

在某些情况下,我们需要为自定义类型实现比较运算符。可以利用std::pair的比较运算符实现这一目标。例如,我们有一个表示二维点的类,需要实现其“小于”运算符:

class Point {
public:Point(int x, int y) : x_(x), y_(y) {}// 实现"小于"运算符,先比较x坐标,然后比较y坐标bool operator<(const Point& other) const {return std::tie(x_, y_) < std::tie(other.x_, other.y_);}private:int x_;int y_;
};

在这个例子中,我们使用std::tie创建了两个包含x_和y_成员的临时std::tuple对象,并使用了std::tuple的比较运算符。这样,我们可以简化比较运算符的实现。

在Lambda表达式中使用std::pair(Using std::pair with Lambda Expressions)

当需要处理复杂的排序或筛选条件时,我们可以将std::pair与lambda表达式结合使用。例如,给定一个包含std::pair的vector,我们想要根据second成员进行降序排序,然后再根据first成员进行升序排序:

std::vector<std::pair<int, int>> data{{1, 4}, {3, 4}, {2, 6}, {4, 6}};std::sort(data.begin(), data.end(), [](const auto& a, const auto& b) {return a.second != b.second ? a.second > b.second : a.first < b.first;
});

在这个示例中,我们使用了lambda表达式作为自定义比较函数,并在函数中利用std::pair的成员进行排序。

d. std::pair与std::optional的结合(Combining std::pair with std::optional)

在某些情况下,我们需要表示一个可选的键值对,例如在查找表中查询时,可能找到或找不到匹配项。这时,我们可以将std::pair与std::optional结合使用。以下是一个示例:

std::map<int, std::string> my_map{{1, "one"}, {2, "two"}};std::optional<std::pair<int, std::string>> find_in_map(int key) {auto it = my_map.find(key);if (it != my_map.end()) {return *it;} else {return std::nullopt;}
}auto result = find_in_map(2);if (result.has_value()) {std::cout << "Found: Key: " << result->first << ", Value: " << result->second << std::endl;
} else {std::cout << "Not found" << std::endl;
}

在这个示例中,find_in_map函数返回一个std::optional<std::pair<int, std::string>>。如果在映射中找到了给定的键,则返回相应的键值对;否则返回std::nullopt。

e. std::pair与智能指针(std::pair and Smart Pointers)

std::pair可以与C++中的智能指针结合使用,以实现自动内存管理。例如,我们可以创建一个包含两个std::shared_ptr的std::pair:

class MyClass {// ...
};std::pair<std::shared_ptr<MyClass>, std::shared_ptr<MyClass>> create_objects() {auto obj1 = std::make_shared<MyClass>();auto obj2 = std::make_shared<MyClass>();return std::make_pair(obj1, obj2);
}// ...auto [obj1, obj2] = create_objects();
// 使用obj1和obj2...

在这个示例中,我们使用了std::shared_ptr和std::pair来自动管理MyClass对象的内存。当std::pair销毁时,std::shared_ptr的引用计数会减少,如果没有其他引用,对象将被自动删除。

通过熟练掌握std::pair的高级用法,我们可以在编写C++代码时更有效地利用std::pair的功能,简化代码并提高编程效率。从结构化绑定、实现比较运算符,到与std::optional、lambda表达式和智能指针结合使用,这些高级用法将使我们在处理复杂问题时能够更好地利用std::pair的特性。

在下一部分中,我们将探讨std::pair的扩展——std::tuple。

std::pair的扩展:std::tuple(Extending std::pair: std::tuple)

std::tuple简介及使用方法(Introduction and Usage of std::tuple)

std::tuple是std::pair的泛化,允许我们存储任意数量的不同类型的数据成员。与std::pair一样,std::tuple也是一个模板类。以下是一个简单的std::tuple示例:

std::tuple<int, std::string, double> t1(1, "one", 1.0);

与std::pair类似,我们可以使用std::make_tuple工具函数创建一个新的std::tuple对象。

auto t2 = std::make_tuple(2, "two", 2.0);

要访问std::tuple中的元素,我们可以使用std::get<>模板函数。注意,此模板函数的参数是在尖括号中的索引,表示要访问的元素的位置。

int first = std::get<0>(t1);
std::string second = std::get<1>(t1);
double third = std::get<2>(t1);

std::tuple与std::pair的比较(Comparing std::tuple and std::pair)

虽然std::tuple具有更高的灵活性,但在某些情况下,std::pair仍然是更合适的选择。以下是两者的主要区别和适用场景:

  1. 成员数量:std::pair只能存储两个数据成员,而std::tuple可以存储任意数量的数据成员。
  2. 访问方式:std::pair中的数据成员可以直接通过其公开的first和second成员访问;而访问std::tuple的数据成员需要使用std::get<>模板函数。
  3. 适用场景:在需要存储两个关联数据的简单情况下,std::pair可能更方便;然而,在需要存储三个或更多关联数据的情况下,std::tuple会更加灵活。

根据实际需求,我们可以在std::pair和std::tuple之间进行选择。接下来,我们将回答关于std::pair的一些常见问题,并总结本文。

常见问题及解答(Frequently Asked Questions and Answers)

问题1:为什么我不能将std::pair或std::tuple的不同类型实例直接赋值给另一个?

答:std::pair和std::tuple是模板类,其类型取决于它们包含的数据成员的类型。如果两个std::pair(或std::tuple)的数据成员类型不完全相同,那么它们的类型也不同。因此,不能直接将一个类型的std::pair(或std::tuple)实例赋值给另一个类型。如果需要进行转换,可以显式地构造一个新的std::pair(或std::tuple)对象并进行赋值。

问题2:我可以将std::pair或std::tuple的成员设为const吗?

答:是的,可以将std::pair或std::tuple的成员设为const。例如:

std::pair<const int, std::string> p(1, "one");

请注意,将数据成员设为const之后,将无法修改其值。

问题3:我可以使用指针或引用作为std::pair或std::tuple的成员类型吗?

答:是的,可以使用指针或引用作为std::pair或std::tuple的成员类型。然而,请注意确保在使用这些成员时始终保持正确的内存管理和生命周期。

问题4:在std::pair中,如何使用自定义类型作为成员?

答:使用自定义类型作为std::pair成员非常简单。您只需要在定义std::pair时,将自定义类型作为模板参数传递给std::pair即可。例如:

class MyClass {// ...
};std::pair<MyClass, int> my_pair;

在这个例子中,我们创建了一个std::pair,其中第一个成员是MyClass类型,第二个成员是int类型。

问题5:如何在std::pair中存储多于两个成员的数据结构?

答:如果需要在std::pair中存储多于两个成员的数据结构,可以使用嵌套的std::pair。例如:

std::pair<int, std::pair<float, std::string>> my_nested_pair;

在这个例子中,我们创建了一个嵌套的std::pair,其中包含一个int类型成员、一个float类型成员和一个std::string类型成员。然而,这种方法可能导致代码可读性降低。在这种情况下,您可能更倾向于使用std::tuple,它可以存储任意数量的成员:

std::tuple<int, float, std::string> my_tuple;

问题6:如何在容器(如std::vector、std::map等)中使用std::pair?

答:将std::pair作为容器的元素类型非常简单。在定义容器时,将std::pair作为模板参数传递给容器即可。例如:

std::vector<std::pair<int, std::string>> my_vector;
std::map<int, std::pair<float, std::string>> my_map;

在这些例子中,我们分别创建了一个包含std::pair<int, std::string>元素的std::vector,以及一个以int为键,以std::pair<float, std::string>为值的std::map。

问题7:如何在std::pair中实现自定义比较?

答:在某些情况下,您可能希望使用自定义比较函数来比较std::pair对象。这可以通过在容器中实现自定义比较函数对象,或者在自定义类型中重载比较运算符来实现。例如:

class MyComparator {
public:bool operator()(const std::pair<int, std::string>& a, const std::pair<int, std::string>& b) const {// 实现自定义比较逻辑// ...}
};std::set<std::pair<int, std::string>, MyComparator> my_set;

在这个例子中,我们实现了一个自定义比较函数对象MyComparator,然后将其作为模板参数传递给std::set,用于比较std::pair<int, std::string>对象。

结语

从心理学角度来看,这篇博客的目的在于传授关于std::pair的知识,激发读者对这个数据结构的学习兴趣,以及展示它在实际编程过程中的应用价值。

  1. 知识结构化:博客以结构化的方式介绍了std::pair的基本概念、创建方法、实际应用、高级用法以及底层原理。这种逐步深入的学习方式有助于读者在心智模型中构建有关std::pair的完整概念,使其容易理解和记忆。
  2. 实际案例:通过具体的编程示例,博客展示了std::pair在实际问题中的应用,如何简化代码和提高编程效率。这有助于读者理解std::pair的实际价值,同时将理论知识与实践相结合,增强学习动力。
  3. 成就感和自我效能:学习std::pair可以帮助读者解决实际编程问题,提高代码质量和效率。当读者在实际应用中看到成果时,他们将获得成就感和自信,从而提高对学习std::pair的兴趣和积极性。
  4. 渐进式挑战:博客内容涵盖了从基础到高级的std::pair用法,这种渐进式的挑战可以激励读者逐步提高自己的编程技能。在解决复杂问题的过程中,读者将不断挖掘std::pair的潜能,激发学习兴趣。
  5. 社会认同:博客提到std::pair在C++编程社区中的广泛应用,这有助于读者认识到学习std::pair的重要性,从而增强他们的学习动力。同时,成为拥有std::pair技能的编程者,可以提高在社区中的认同感和地位。

相关文章:

探秘C++中的神奇组合:std--pair的魅力之旅

探秘C中的神奇组合&#xff1a;std::pair的魅力之旅 引言std::pair简介及基本概念&#xff08;An Overview and Basic Concepts of std::pair&#xff09;std::pair的结构及构造方法&#xff08;Structure and Construction Methods of std::pair&#xff09;std::pair的常用成…...

Win10搭建我的世界Minecraft服务器「内网穿透远程联机」

文章目录 1. Java环境搭建2.安装我的世界Minecraft服务3. 启动我的世界服务4.局域网测试连接我的世界服务器5. 安装cpolar内网穿透6. 创建隧道映射内网端口7. 测试公网远程联机8. 配置固定TCP端口地址8.1 保留一个固定tcp地址8.2 配置固定tcp地址 9. 使用固定公网地址远程联机 …...

基于springboot和ajax的简单项目 02 代码部分实现,xml文件sql语句优化 (中)

上次说到了log/log_list.html的doGetObjects()&#xff0c;其中有doFindPageObjects&#xff08;&#xff09;方法。 找到全部的日志对象&#xff0c;并且输出到div上。这里是后台的代码。 01.pojo对象&#xff0c;这里需要序列化保存。序列化的作用是保存对象到内存缓存中&am…...

LNMP架构部署

L&#xff1a;Linux A:Apache M:Mysql P:PHP 各组件的主要作用如下&#xff1a; (平台)Linux&#xff1a;作为LAMP架构的基础&#xff0c;提供用于支撑Web站点的操作系统&#xff0c;能够与其他三个组件提供更好的稳定性&#xff0c;兼容性(AMP组件也支持Windows、UNIX等平…...

SpringBoot 防护XSS攻击

目录 一、前言 1.1、XSS攻击流程 1.2、XSS攻击分类 1.3、攻击方式 二、解决方案 2.1、SPRINGBOOT XSS过滤插件&#xff08;MICA-XSS&#xff09; 2.2、MICA-XSS 配置 三、项目实战 3.1、项目环境 3.2、测试 3.2.1、测试GET请求 3.2.2、测试POST请求 3.2.3、测试POS…...

iOS 吸顶效果

项目中&#xff0c;在列表向上滚动时&#xff0c;有时需要将某个控件置顶&#xff0c;这就是我们常见的吸顶效果。 1. UITableView 吸顶效果 UITableView是自带吸顶效果&#xff0c;我们把需要置顶的控件设置为SectionHeaderView&#xff0c;这样在滚动时&#xff0c;该控件会…...

文本翻译免费软件-word免费翻译软件

好用的翻译文件软件应该具备以下几个方面的特点&#xff1a;支持多种文件格式&#xff0c;翻译结果准确可靠&#xff0c;界面操作简便易用&#xff0c;价格实惠&#xff0c;用户体验舒适。以下是几个好用的翻译文件软件&#xff1a; 1.147cgpt翻译软件 翻译软件特点&#xff1…...

redis 主从模式、哨兵模式、cluster模式的区别

参考&#xff1a; ​https://blog.csdn.net/qq_41071876/category_11284995.html https://blog.csdn.net/weixin_45821811/article/details/119421774 https://blog.csdn.net/weixin_43001336/article/details/122816402 Redis有三种模式&#xff0c;分别是&#xff1a;主…...

SDL(2)-加载图片

加载BMP 1.使用SDL_init初始化SDL库 2.使用SDL_CreateWindow创建一个窗口 3.使用SDL_GetWindowSurface获取创建窗口的surface 4.使用SDL_LoadBMP加载一张BMP图片 5.使用SDL_BlitSurface将加载的bmp surface拷贝到窗口的surface 6.使用SDL_UpdateWindowSurface更新到窗口 …...

指针数组和数组指针

指针和数组都是C语言中非常重要的概念。它们各自有其用途和应用场景。本文将介绍指针数组和数组指针&#xff0c;两者的区别和用法。 指针数组 指针数组是指一个数组&#xff0c;其中的每个元素都是一个指针类型。例如&#xff0c;下面这个定义了3个字符型指针的数组&#xf…...

程序员最常见的谎言

小伙伴们大家好&#xff0c;我是阿秀。 上周看到知乎上有位网友总结了自己的10年程序员生涯中最常说的一些谎言&#xff0c;一共有15条&#xff0c;看完我直呼内行&#xff01;&#xff01; 全中&#xff01;每一枪都中了&#xff01;每一条我都说过。 我基本都说过他说过的那些…...

hypothesis testing假设检验

假设检验是什么 比如一家巧克力工厂生产的巧克力每个1g&#xff0c;一个工人说&#xff0c;机器在维修之后生产的巧克力不是1g&#xff0c;为了验证工人说的是否正确&#xff0c;需进行假设检验。 随机挑选50个巧克力&#xff0c;计算平均重量。 H0&#xff1a;每个巧克力1g H…...

ChatGPT扩展系列之解决ChatGPT 被大面积封号的终极方案

ChatGPT扩展系列之解决ChatGPT 被大面积封号的终极方案 本节介绍了一个解决ChatGPT在中国大陆无法使用和担心被封号的问题的方法。近期有很多亚洲用户被封号,原因是有人滥用API接口或者批量注册账号,不符合官方规定。对于这个问题,提出了一个解决方法,可以在中国大陆无需翻…...

如何在DevOps中进行API生命周期管理?

引言 随着DevOps理念在中国企业当中的普及和发展&#xff0c;中国企业DevOps落地成熟度不断提升&#xff0c;根据中国信通院的数据已有近6成企业向全生命周期管理迈进。而在研发全生命周期管理之中&#xff0c;API管理的地位愈发显得重要。随着API数量的大幅增长&#xff0c;也…...

嵌套列表,与摩尔投票进阶

title: “Python fishC 22” author: “hou wei” date: “2023-04-16” output: html_document knitr::opts_chunk$set(echo TRUE)问答题 0.请问 运算符和 is 运算符有什么区别呢&#xff1f; 在Python中运算符用于比较两个变量的值是否相等&#xff0c;而is运算符用于判断…...

ChatGPT原理解释

写了一本介绍ChatGPT原理的课程 结构如下 01、介绍ChatGPT及其原理 1.1 ChatGPT的概述 1.2 什么是自然语言处理&#xff08;NLP&#xff09; 1.3 深度学习与NLP的关系 1.4 GPT模型的介绍 02、GPT原理探讨 2.1 GPT模型的输入与输出 2.2 GPT模型的结构 2.3 GPT模型的预训练方法…...

【配电网故障重构SOP】基于二阶锥松弛的加光伏风机储能进行的配电网故障处理和重构【考虑最优潮流】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

ajax 的入门案例

一、ajax ajax&#xff0c;Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML 同步&#xff1a;伴随着页面的刷新或跳转&#xff0c;即全局刷新&#xff1b;同步请求会阻塞代码的执行&#xff0c;即同步请求会一个一个的执行 异步&#xff1a;在不刷新页面…...

Flutter TextField 交互实例 —— 新手礼包

大家好&#xff0c;我是 17。 新手礼包一共 3 篇文章&#xff0c;每篇都是描述尽量详细&#xff0c;实例讲解&#xff0c;包会&#xff01; Flutter Row 实例 —— 新手礼包Flutter TextField UI 实例 —— 新手礼包Flutter TextField 交互实例 —— 新手礼包 本篇包含所有常…...

折叠屏:手机厂商的「续命良药」

【潮汐商业评论/文】 作为办公室的“时尚达人”&#xff0c;Wendy又为自己添置了一款新时尚单品——折叠手机。 “没有哪个女孩子能拒绝一款小巧又时尚的折叠手机吧&#xff0c;我心动了好久&#xff0c;终于狠狠心买了一部。”提起自己的折叠手机&#xff0c;Wendy的眼里满是…...

RabbitMQ 保证消息不丢失的几种手段

文章目录 1.RabbitMQ消息丢失的三种情况2.RabbitMQ消息丢失解决方案2.1 针对生产者2.1.1 方案1 &#xff1a;开启RabbitMQ事务2.1.2 方案2&#xff1a;使用confirm机制 2.2 Exchange路由到队列失败2.3 RabbitMq自身问题导致的消息丢失问题解决方案2.3.1 消息持久化2.3.2 设置集…...

nginx配置

单线程应用 稳定性高 系统资源消耗低 线程切换消耗小 对HTTP并发连接处理能力高 单台服务器可支持2w个并发请求 nginx与apache区别 Nginx相对于Apache的优点: 轻量级&#xff0c;同样是 web 服务&#xff0c;比Apache 占用更少的内存及资源&#xff0c;高并发&#xff0…...

linux从入门到精通 第一章centos7里tomcat,jdk,httpd,mysql57,mysql80的安装

配置centos运行环境 一 安装httpd,tomcat,jdk,mysql1 安装httpd2 安装tomcat3 安装jdk 三 MySql的安装1 克隆出来两台虚拟机2 配置虚拟机3 链接xhsell4 链接xftp5 mysql8的安装6 mysql5.7的安装 一 安装httpd,tomcat,jdk,mysql 1 安装httpd 下载httpd yum -y install httpd关…...

ChatGPT 速通手册——开源社区的进展

开源社区的进展 在 ChatGPT 以外&#xff0c;谷歌、脸书等互联网巨头&#xff0c;也都发布过千亿级参数的大语言模型&#xff0c;但在交谈问答方面表现相对 ChatGPT 来说都显得一般。根据科学人员推测&#xff0c;很重要的一部分原因是缺失了RLHF(Reinforcement Learning with…...

string类

string - C Reference (cplusplus.com) 引入&#xff1a; ASCII码表------>Unicode 其中又进行了分类&#xff1a; &#xff08;UTF--8兼容ASCII码表&#xff09; 等等等等 &#xff08;不但迭代和更新&#xff09; 例&#xff1a; 目录 正文开始&#xff01;&#xff0…...

LLM总结(持续更新中)

引言 当前LLM模型火出天际&#xff0c;但是做事还是需要脚踏实地。此文只是日常学习LLM&#xff0c;顺手整理所得。本篇博文更多侧重对话、问答类LLM上&#xff0c;其他方向&#xff08;代码生成&#xff09;这里暂不涉及&#xff0c;可以去看综述来了解。 之前LLM模型梳理 …...

【GPT4】微软 GPT-4 测试报告(2)多模态与跨学科的组合

欢迎关注【youcans的AGI学习笔记】原创作品&#xff0c;火热更新中 微软 GPT-4 测试报告&#xff08;1&#xff09;总体介绍 微软 GPT-4 测试报告&#xff08;2&#xff09;多模态与跨学科能力 微软 GPT-4 测试报告&#xff08;3&#xff09;编程能力 微软 GPT-4 测试报告&…...

Celery使用教程完整版【从安装到启用】

Celery是一个基于Python开发的异步任务队列&#xff0c;可以实现任务的异步调度和处理。 以下是Celery使用教程的基本步骤&#xff1a; 安装Celery库 使用pip命令安装Celery库&#xff1a; pip install celery 创建Celery实例 在项目的Python文件中创建Celery实例&#x…...

【Java技术指南】「JPA编程专题」让你不再对JPA技术中的“持久化型注解”感到陌生了

JPA编程专题 JPA的介绍JPA的介绍分析JPA注解总览JPA实体型注解EntityTableTableGeneratorTableGenerator 属性 Temporal TransientColumnColumn 属性ColumnUniqueConstraint属性状态 VersionVersion Embeddable 和 EmbeddedEmbedded EmbeddedIdMappedSuperclassEntityListeners…...

Java基础:IO流有哪些,各有什么特点和功能

具体操作分成面向字节(Byte)和面向字符(Character)两种方式。 如下图所示&#xff1a; IO流的三种分类方式 IO流的层次结构 IO流的常用基类有&#xff1a; 字节流的抽象基类&#xff1a;InputStream和OutputStream&#xff1b; 字符流的抽象基类&#xff1a;Reader和Writer…...