zoukankan      html  css  js  c++  java
  • [C++ STL] 一个泛型算法的设计

    从一个简单的需求开始,从一个vector中返回小于10的数的vector,那我们会写如下的函数:
    vector<int> less_than_ten(vector<int>& vec) {
         vector<int> result;
         for(int i=0; i<vec.size(); i++) {
              if (vec[i] < 10) {
                   result.push_back(vec[i]);
              }
         }
         return result;
    }
    这个函数只局限于能返回小于10的数,我想能够返回小于我指定的数,于是改成了如下的函数:
    vector<int> less_than(vector<int>& vec, int val) {
         vector<int> result;
         for (int i=0; i < vec[i]; i++) {
              if (vec[i] < val)
                   result.push_back(vec[i]);
         }
         return result;
    }
    然后我又考虑到,不应该仅仅是小于,还有可能是大于,或等于。参数化比较函数,于是有了如下的版本 :
    bool less_than(int x, int y) {
         return x < y;
    }
    bool greater_than(int x, int y) {
         return x > y;
    }
    vector<int> filter(vector<int>& vec, int val, bool (*pred)(int,int)) {
         vector<int> result;
         for (int i=0; i < vec.size(); i++) {
              if (pred(vec[i],val))
                   result.push_back(vec[i]);
         }
         return result;
    }
    不能仅仅只是int型,如果我们还要float,long,char型 难道都要写一个吗?,不需要,只要使用模板就可以了:
    template<typename elemType>
    vector<elemType> filter(vector<elemType>& vec, elemType val, bool (*pred) (elemType,elemType)) {
         vector<elemType> result;
         for (int i=0; i < vec.size(); i++) {
              if (pred(vec[i],val))
                   result.push_back(vec[i]);
         }
         return result;
    }
    此时需要注意的是调用的时候,必须保证这三个参数的类型要一致。
    在广泛一点我们不仅仅是想使用vector容器,也可以用别的容器,返回的是一个iterator 指向容器中一个元素。
    我们使用C++库<algorithm>中的提供的函数对象,和泛型算法.
    C++ algorithm库里面提供的 function object 有plus<>,minus<>等等。
    我们可以使用bind2nd 把它绑定到一个固定的值,与一个固定值进行比较
    template<typename elemType,typename Com>
    vector<elemType> filter(vector<elemType>& vec, elemType val, Com pred) {
         vector<elemType> result;
         vector<elemType>::iterator it;
         for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++)
              result.push_back(*it);
         return result;
    }
    find_if是在一个范围内查找符合条件的数,并返回该数的位置。 找到最后就是vec.end()了。
    for(; (it = find_if(vec.begin().vec.end(),bind2nd(pred,val))) != vec.end(); it++) 这个就是遍历从vec 找到所有符合pred 这个比较函数的值,并把它添加到result里,然后返回。
    我们没有必要一开始就能立即写出泛型的函数,可以从简单的开始,一步一步抽象,并参数化。每次写完一个函数的时候,我们应该思考它的扩展性,看能否使其更灵活。这样做非常有助于我们的提高。好的代码要写两次。
    参考书目:
    《Essential C++》
  • 相关阅读:
    JVM运行时数据区及对象在内存中初始化的过程
    一文搞懂List 、List<Object>、List<?>的区别以及<? extends T>与<? super T>的区别
    Java中创建泛型数组
    JavaBean详解
    Java常用命令及参数
    一文彻底搞懂Java中的环境变量
    类型信息
    java中的数组
    URL与URI的区别
    上行速率和下行速率
  • 原文地址:https://www.cnblogs.com/robbychan/p/3787000.html
Copyright © 2011-2022 走看看