C++标准库中的辅助函数与时间处理
立即解锁
发布时间: 2025-08-22 00:43:47 阅读量: 2 订阅数: 16 


深入解析C++标准库:从入门到精通
### C++标准库中的辅助函数与时间处理
#### 1. 辅助函数
C++标准库提供了一些小型辅助函数,用于处理最小值和最大值、交换值或提供补充的比较运算符。
##### 1.1 处理最小值和最大值
`<algorithm>`头文件提供了一系列实用函数,用于处理两个或多个值的最小值和/或最大值。这些函数自C++11起提供了`minmax()`函数和用于初始化列表的版本。
| 操作 | 效果 |
| --- | --- |
| `min(a,b)` | 使用`<`比较,返回`a`和`b`中的最小值 |
| `min(a,b,cmp)` | 使用`cmp`比较,返回`a`和`b`中的最小值 |
| `min(initlist)` | 使用`<`比较,返回`initlist`中的最小值 |
| `min(initlist,cmp)` | 使用`cmp`比较,返回`initlist`中的最小值 |
| `max(a,b)` | 使用`<`比较,返回`a`和`b`中的最大值 |
| `max(a,b,cmp)` | 使用`cmp`比较,返回`a`和`b`中的最大值 |
| `max(initlist)` | 使用`<`比较,返回`initlist`中的最大值 |
| `max(initlist,cmp)` | 使用`cmp`比较,返回`initlist`中的最大值 |
| `minmax(a,b)` | 使用`<`比较,返回`a`和`b`中的最小值和最大值 |
| `minmax(a,b,cmp)` | 使用`cmp`比较,返回`a`和`b`中的最小值和最大值 |
| `minmax(initlist)` | 使用`<`比较,返回`initlist`中的最小值和最大值 |
| `minmax(initlist,cmp)` | 使用`cmp`比较,返回`initlist`中的最小值和最大值 |
`minmax()`函数返回一个`pair<>`,其中第一个值是最小值,第二个值是最大值。对于两个参数的版本,`min()`和`max()`在两个值相等时返回第一个元素;对于初始化列表,返回多个最小或最大元素中的第一个。
需要注意的是,接受两个值的版本返回引用,接受初始化列表的版本返回值的副本:
```cpp
namespace std {
template <typename T>
const T& min (const T& a, const T& b);
template <typename T>
T min (initializer_list<T> initlist);
...
}
```
原因是对于初始化列表,需要一个内部临时变量,返回引用会导致悬空引用。
这些函数也可以提供一个比较准则作为额外参数:
```cpp
namespace std {
template <typename T, typename Compare>
const T& min (const T& a, const T& b, Compare cmp);
template <typename T, typename Compare>
T min (initializer_list<T> initlist, Compare cmp);
...
}
```
比较参数可以是一个函数或函数对象。
以下是一个使用特殊比较函数作为参数调用`max()`函数的示例:
```cpp
// util/minmax1.cpp
#include <algorithm>
// function that compares two pointers by comparing the values to which they point
bool int_ptr_less (int* a, int* b)
{
return *a < *b;
}
int main()
{
int x = 17;
int y = 42;
int z = 33;
int* px = &x;
int* py = &y;
int* pz = &z;
// call max() with special comparison function
int* pmax = std::max (px, py, int_ptr_less);
// call minmax() for initializer list with special comparison function
std::pair<int*,int*> extremes = std::minmax ({px, py, pz}, int_ptr_less);
...
}
```
也可以使用lambda表达式指定比较准则,并使用`auto`避免显式声明返回值:
```cpp
auto extremes = std::minmax ({px, py, pz}, [](int*a, int*b) {
return *a < *b;
});
```
需要注意的是,`min()`和`max()`的定义要求两个类型匹配,否则会报错。但可以显式指定模板参数的类型:
```cpp
int i;
long l;
...
std::max(i,l); // ERROR: argument types don’t match
std::max({i,l}); // ERROR: argument types don’t match
std::max<long>(i,l); // OK
std::max<long>({i,l}); // OK
```
##### 1.2 交换两个值
`swap()`函数用于交换两个对象的值。其通用实现定义在`<utility>`中:
```cpp
namespace std {
template <typename T>
inline void swap(T& a, T& b) ... {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
}
```
在C++11之前,值是通过赋值或复制的,而现在内部使用移动语义。
调用`std::swap(x,y)`可以交换两个任意变量`x`和`y`的值,但前提是参数类型提供了移动或复制语义。
自C++11起,标准库还提供了数组的重载版本:
```cpp
namespace std {
template <typename T, size_t N>
void swap (T (&a)[N], T (&b)[N])
noexcept(noexcept(swap(*a,*b)));
}
```
使用`swap()`的一个重要优点是可以通过模板特化或函数重载为更复杂的类型提供特殊实现,从而提高性能。例如:
```cpp
class MyContainer {
private:
int* elems;
int numElems;
public:
...
// implementation of swap()
void swap(MyContainer& x) {
std::swap(elems,x.elems);
std::swap(numElems,x.numElems);
}
...
};
// overloaded global swap() for this type
inline void swap (MyContainer& c1, MyContainer& c2)
noexcept(noexcept(c1.swap(c2)))
{
c1.swap(c2);
}
```
需要注意的是,两个类型必须匹配,否则会报错。
##### 1.3 补充比较运算符
四个函数模板通过调用`==`和`<`运算符定义了`!=`、`>`、`<=`和`>=`比较运算符。这些函数声明在`<utility>`中:
```cpp
namespace std {
namespace rel_ops {
template <typename T>
inline bool operator!= (const T& x, const T& y) {
return !(x == y);
}
template <typename T>
inline bool operator> (const T& x, const T& y) {
return y < x;
}
template <typename T>
inline bool operator<= (const T& x, const T& y) {
return !(y < x);
}
template <typename T>
inline bool operator>= (const T& x, const T& y) {
return !(x < y);
}
}
}
```
要使用这些函数,只需定义`<`和`==`运算符,然后使用`using namespace std::rel_ops`即可自动定义其他比较运算符。
例如:
```cpp
#include <utility>
class X {
public:
bool operator== (const X& x) const;
bool operator< (const X& x) const;
...
};
void foo()
{
using namespace std::rel_ops;
X x1, x2;
...
if (x1 != x2) {
...
}
```
0
0
复制全文
相关推荐










