zoukankan      html  css  js  c++  java
  • 给RArray和CArray加上自己的泛型算法(转)

    给RArray和CArray加上自己的泛型算法(原创,先天残贴)

    4已有 213 次阅读  2010-08-15 16:46   标签:  CArray  RArray  泛型  算法  原创 
    RArray和CArray应该是symbian里用的最多的两个容器类了。
    RArray有自己的特化版本<TInt>和<TUint>,有存指针的版本;CArray也可细分为n多类(我实在是记不住,sdk里可以查到)。
    如此繁多的类,他们都有一个自己的Sort()方法。这个方法是symbian官方提供的。不过如果用Sort(),需要大家玩命的学习,况且也不好学,很多人也不愿意学。

    最近我写了一套泛型算法,可以稍微解决一下sort的问题。
    思路其实很简单,我不可能去改系统api,但是我可以自己写n多的函数来调用,无非是把array实例传进去就行了。
    传统调用可能是:
    RArray array;
    array.Sort(xxxx);
    现在的调用可能是:
    RArray array;
    MySort(array);

    细节这块,因为RArray本身就是模板类,那么,以RArray<T>为参数的函数,应该就是一个模板函数。
    接下来,就定一定都要实现哪些算法,除了上边说到的排序,还可以有像find_if,count_if,for_each这样的强力+短小+有用的,直接仿照stl就好。

    以find_if为例,如果我写这个函数,都需要哪些模板参数呢?
    想一想,我外部在调用的时候,应该是这样的形式:
    RArray<TInt> array;
    TInt index = FindIf(array, functor???);
    FindIf是模板函数,他可以自动推导模板参数,这样就省得自己写<xxx,xxx,xxx>了。
    array本身就是模板类了,functor可能是一个静态函数或者一个简单对象,用来做具体的匹配的判断。
    函数返回是一个index,返回值应该是很简单的,-1就是没找到,否则就返回第一次找到的index。

    ok,写个原型,可能是这样的:
    template<class T1, template<class> class T2, class T3>
    TInt FindIf(const T2<T1>& aArray, T3 aFunctor);
    这里用到一个技巧,就是template template class,要不然,RArray传不进去。。
    T1是RArray的模板参数TInt,T2就是RArray,T2必须是一个模板类,T3是functor的类型(函数指针或者对象的类型),然后aFunctor做一个copy(忘了看哪本书说要copy)。
    关于这个aFunctor,我要做个规范,首先他应该返回一个TBool,用来表示匹配的结果,他的参数,应该就是从Array里取出来的某一个元素,这个元素最好是const &的。
    都想得差不多了,就可以写了
    template<class T1, template<class> class T2, class T3>
    TInt FindIf(const T2<T1>& aArray, T3 aFunctor);
    {
      for(i xxx)
      {
       if(aFunctor(aArray.At(i)) return i;
      }
      return -1;
    }
    简单吧,可是这里有一个重大的问题~

    我如何能保证aArray.At(i) 这种形式是可用的? 
    如果是RArray,他根本就没有能用的At()成员函数,而是operator []。
    那么对于RArray,我就不能再用FindIf了,否则肯定编译不过去。

    加细节吧,我还需要规范一下aArray的调用。我需要保证,不管aArray是什么类型,在算法里都使用同一个办法,来达到目的。
    我又一次想到了模板类 囧:可以用模板类来实现,可以特化出不同版本,来适应不同的array的类。
    这个模板类应该是工具类,他不需要被继承,也不需要有成员函数。
    这个类名,可以叫ArrayUtils。
    对于aArray.At(i),我就可以定一个静态的成员函数,给定aArray和i,返回一个元素。
    代码类似于:
    template<class T1, template<class > class T2>
    class ArrayUtils
    {
    public:
        typedef T1 DataType;
        typedef T2<T1> ContainerType;
    public:
        static const DataType& At(const ContainerType& aC, TInt aIndex)
        {
            return aC[aIndex];
        }
    };
    这里是对于RArray来的。

    因为这是商业代码,所以不好发出来。
    本文到这里就结束了。。。
    我以后可能还要修改。。。

    发表评论评论 (4 个评论)

    • manbuzhe 2010-08-15 16:53
      可以更优化下, return aC[aIndex]; 这需要外部的Container必须实现 operator 【】 接口,其实可以借鉴stl iterator的实现方案。
    • whhema 2010-08-15 16:57
      manbuzhe: 可以更优化下, return aC[aIndex]; 这需要外部的Container必须实现 operator 【】 接口,其实可以借鉴stl iterator的实现方案。
      好像还真是这样的,可以啊
    • Roulong 2010-08-16 21:25
      天残地缺。。。。神雕侠侣。。。
    • whhema 2010-08-17 08:49
      Roulong: 天残地缺。。。。神雕侠侣。。。
      哈哈,我这个是天生的,不是后天的天残地缺
  • 相关阅读:
    前端利用百度开发文档给的web服务接口实现对某个区域周边配套的检索
    libevent源码学习(13):事件主循环event_base_loop
    libevent源码学习(11):超时管理之min_heap
    libevent源码学习(10):min_heap数据结构解析
    libevent源码学习(8):event_signal_map解析
    libevent源码学习(9):事件event
    libevent源码学习(6):事件处理基础——event_base的创建
    libevent源码学习(5):TAILQ_QUEUE解析
    仿Neo4j里的知识图谱,利用d3+vue开发的一个网络拓扑图
    element表格内每一行删除提示el-popover的使用要点
  • 原文地址:https://www.cnblogs.com/yaoliang11/p/1865960.html
Copyright © 2011-2022 走看看