在 C 語言中實現模板函數的方法

來源:互聯網
上載者:User
在 C 語言中實現模板函數的方法:

 

各種用 C 語言實現的模板可能在使用形式上有所不同。

 

現以一個求和函數 Sum 為例,用 C++ Template 可寫如下:

 

template<class T, class R>  R Sum(const T *array, int n)

{

            R sum = 0;

            for (int i = 0 ; i < n ; ++i)

                        sum += i;

            return sum;

}

如果不是內建類型,該模板隱式地需要 有R R::operator+=(T)運算子可用。

 

1.    使用函數指標作為 Functor 替換者

Typedef struct tagAddClass

{

            Void (*add)(char* r1, const char* r2);

            Int elemSize;

            Char  sum[MAX_ELEM_SIZE];

} AddClass;

void Sum(AddClass* self, const char* array, int n)

{

            for (int i = 0 ; i < n ; ++i)

                        self->add(self->sum, array + i*self->elemSize);

}

 

使用時:

…..

 

Void AddInt(char* r1, const char* r2)

{

            *(long*)r1 += *(int*)r2;

}

AddClass addClass = {AddInt, 2, 0 };

Int array[100];

Read(array);

Sum(&addClass, array, 100);

…..

 

2.    用宏作為Functor的替換者

#define  GenSumFun(SumFunName, Add, RetType, ElemType)           /

RetType SumFunName (const ElemType *array, int n)  /

{                                                                      /

            RetType sum = 0;                                 /

            for (int i = 0 ; i < n ; ++i)                       /

                        Add(sum, i);                             /

            return sum;                                           /

}

使用時:

#define AddInt(x, y)  ((x) += (y))

GenSumFun(SumInt, AddInt, long, int)

…..

Int array[100];

Read(array);

Long sum = SumInt(array, 100);

…..

 

3.    所有可替換參數均為宏

至少需要一個額外的檔案(實現檔案)為 impsum.c

 

/* impsum.c */

RetType FunName(const ElemType *array, int n)

{                                                                     

            RetType sum = 0;                                

            for (int i = 0 ; i < n ; ++i)                      

                        Add(sum, i);                            

            return sum;                                          

}

 

使用時:

#undef  RetType

#undef  FunName

#undef  ElemType

#undef  Add

#define AddInt(x, y)  ((x) += (y))

#define RetType long

#define FunName SumInt

#define ElemType int

#define Add  AddInt

 

#include impsum.c

 

…..

Int array[100];

Read(array);

Long sum = SumInt(array, 100);

…..

 

4.    總結:

第一種方法,易於跟蹤調試,但是效率低下,適用於對可變函數(函數指標)的效率要求不高,但程式出錯的可能性較大(複雜),模板函數(Sum)本身很複雜,模板參數也比較複雜(add)的場合。

第二種方法,效率高,但很難跟蹤調試,在模板函數和模板參數本身都很複雜的時候更是如此。

第三種方法,是我最近幾天才想出的,我認為是最好的,在模板參數(Add)比較複雜時可以用函數(第二種也可以如此),簡單時可以用宏,並且,易於調試。在模板函數本身很複雜,而模板參數比較簡單時更為優越。但是,可能有點繁瑣。

 

一般情況下,沒有必要做如此勞心的工作,一切交給編譯器去做就行了。但是本人在開發一個檔案系統時,由於是基於一種少見的平台,沒有可用的C++編譯器,有幾個函數,除了其中的類型不同(uint16和uint32),和幾個可參數化的宏不同,其它地方完全相同,而函數本身很複雜(兩百多行代碼)。Copy出幾個完全類似的函數副本,維護起來特別煩人。非常需要如此的編程模式,故此,分享出來,大家共同探討。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.