2015年05月19日
算法程序库中有三个辅助函数,一个用来在二值中判断最大的,一个用来判断最小的,一个用来交换
Min & Max
min 和 max 通常可以用三元操作符?:来判断大小,但是,algorithm算法库中还提供另外一个版本,接受一个额外的template参数作为比较准则:
template <class T, class Compare>
inline const T& min(const T& a, const T& b, Compare comp)
{
return comp(b, a) ? b : a;
}
template <class T, class Compare>
{
inline const T& max(const T& a, const T& b, Compare comp)
{
return comp(a, b) ? b : a;
}
}
上述代码中的comp就是所谓的“template参数”,通过上述代码我们看到,其实comp是一个函数或者仿函数(理解为函数的一种),用来返回一个bool值,在min和max中根据这个布尔值来确定大小准则。
有一点需要注意:min()和max()需要他们所接受的两个参数的类型一致,如果不一致,将会报错。
不过到时可以显式的声明参数类型,如:
int i; long l;
l = max<long>(i , l);//将max声明为long类型,那么会有将i转换为long的隐式转换
swap
在《C++标准程序库》中,关于swap的部分比较晦涩,主要是通过一段代码来讲解swap的好处的。文字部分如下:
swap()的最大的优势在于,通过template specialization(模板特化)或function overloading(函数重载),我们可以为更复杂的类型提供特殊的实作版本(应该理解为实际使用的版本);我们可以交换对象内部称愿,不必劳师动众的反复赋值,这无疑大大节约时间。标准程序库中的所有容器以及strings都运用了这项技术。
我们先看一下与这段文字匹配的代码是怎么样的:
class MyContainer
{
private:
int* elems;
int numElems;
public:
void swap(MyContainer& x)
{
std::swap(elems, x.elems);
std::swap(numElems, x.numElems);
}
};
//全局swap函数
inline void swap(MyContainer& c1, MyContainer& c2)
{
c1.swap(c2);
}
单看这段代码也觉得莫名其妙,似乎根本没有必要如此定义一个简单的swap函数。但是结合上面的文字,那么我们应该这样理解这段代码:
- MyContainer类中的swap成员函数只能绑定一个具体的对象,换句话说,只能出现诸如c1.swap(c2)这样的调用。在swap成员函数中使用了两次原始的swap用来交换数据成员。
- 全局的swap函数的目的是能够直接使用类似于swap(c1, c2)这样的调用,于是直接在全局swap钟调用了其中的一个参数的swap成员函数。
我个人觉得这样并不比直接使用c1.swap(c2)这样的形式更为简练或有别的好处。但是使用书上的方法书写swap函数的话,是对swap的重载,能减少接口参数的差异(就是我在不知道swap函数是怎么定义的时候也能猜出来大致应该怎么写swap啦)。
头文件cstdlib中exit和abort的区别
在头文件cstdlib中,exit()和abort()都是用来在任意地点终止程序运行的函数,它们不会返回main函数。
区别:
- exit()会销毁所有的static对象,将所有的缓冲区(buffer)清空,关闭所有的I/O通道,然后终止程序(之前会调用经由atexit()登录的函数)。如果atexit()登录的函数抛出异常,会调用terminate()。
- abort()会立即终止函数,不做任何清理工作。
这两个函数都不会销毁局部对象,为确保所有的局部对象的析构函数获得调用,应该用异常或正常返回机制由main函数离开。