STL主要由两种组件构成:容器和泛型算法。
泛型算法提供了许多作用于容器类以及数组类型的操作。所谓泛型,是因为算法与元素的类型无关,容器类型也无关。
泛型算法通过函数模板(function template)实现与元素类型无关;而与容器类型无关,则是通过不直接操作容器,而是使用迭代器(iterator)来操作容器实现的。
/*
新目标,给一个整数vector,要求返回一个新的vector,其中包含原vector中小于10的所有元素
*/
vector<int> less_than_10(const vector<int>& vec) {
vector<int> new_vec;
for (int i = 0;i < vec.size();++i) {
if (vec[i] < 10)
new_vec.push_back(vec[i]);
}
return new_vec;
}
/*
如果想指定小于某个数值,则可以添加一个参数改为vector<int> less_than(const vector<int>& vec,int less_than_value);
*/
/*
下一个任务是允许用户指定不同比较操作,比如大于、小于
有一种解决办法是,加入第三参数pred,这是一个函数指针,其参数列表有两个,返回值为bool,
此时该函数名改为filter更合适
*/
vector<int> filter(const vector<int>& vec, const int& compare_value, bool (*pred)(int, int)) {
vector<int> new_vec;
for (int i = 0;i < vec.size();++i) {
if (pred(vec[i], compare_value))
new_vec.push_back(vec[i]);
}
return new_vec;
}
/*
以下是可以传给filter的关系比较函数
*/
bool greater_than(int value1, int value2) {
return value1 > value2 ? true : false;
}
bool less_than(int value1, int value2) {
return value1 < value2 ? true : false;
}
/*
这个filter()使用for循环遍历每个元素,接下来使用find_if()代替for循环,使用find_if()反复
查找数列中符合条件的元素,该条件由用户指定的函数指针定义。
条件假设为“找到每个等于10的元素”
接下来重新实现filter以便支持find_if()
*/
/*
function object adapter会对function object进行修改操作,使function object的参数绑定至指定值
,使二元function object转化为一元function object
bind1st绑定第一操作数,bind2nd绑定第二操作数
*/
vector<int> filter(const vector<int>& vec, int value, less<int>& lt) {
vector<int> new_vec;
vector<int>::const_iterator it = vec.begin();
while ((it = find_if(vec.begin(), vec.end(), bind2nd(lt, value))) != vec.end()) {
new_vec.push_back(*it);
it++;//找到后,从被找到的下一个开始
}
return new_vec;
}
/*
接下来消除filer与vector元素类型、以及容器类型的依赖关系,以增加filter的泛化性
*/
/*
通过改为function template消除对元素类型的依赖
*/
template <typename elemType>
vector<elemType> filter(const vector<elemType>& vec, elemType value, less<elemType>& lt) {
vector<elemType> new_vec;
vector<elemType>::const_iterator it = new_vec.begin();
while ((it = find_if(vec.begin(), vec.end(), bind2nd(lt, value))) != vec.end()) {
new_vec.push_back(*it);
it++;//找到后,从被找到的下一个开始
}
return new_vec;
}
/*
为了消除容器类型的依赖,传入一对iterator[begin,end),并在参数列表中增加另一个iterator,指定从何处开始复制元素
还消除了比较关系的依赖
*/
template <typename InputIterator,typename OutputIterator,typename elemType,typename Comp>
OutputIterator filter(InputIterator first, InputIterator last, OutputIterator at, const elemType &value, Comp pred) {
while ((first = find_if(first, last, bind2nd(pred, value))) != last) {
cout << "found value:" << value << endl;
*at++ = *first++;//逐一赋值到新数组
}
return at;
}