2012-01-18 85 views
1

有一個包含三個模板的類。具有不同參數個數的模板函數

#if defined(USE_CACHE_FALRU) 
template class Cache<FALRU>; 
#endif 

#if defined(USE_CACHE_IIC) 
template class Cache<IIC>; 
#endif 

#if defined(USE_CACHE_LRU) 
template class Cache<LRU>; 
#endif 

這些模板具有共同的功能:

FALRUBlk* accessBlock(Addr addr, int &lat, int context_src, int *inCache = 0); 
IICTag* accessBlock(Addr addr, int &lat, int context_src); 
BlkType* accessBlock(Addr addr, int &lat, int context_src); 

正如你所看到的,對於一個模板參數數目不同於別人。

現在緩存(),有它調用accessBlock()函數

template<class TagStore> 
bool Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk, int &lat, PacketList &writebacks) 
{ 
... 
blk = tags->accessBlock(pkt->getAddr(), lat, id); 
... 
} 

在confing文件,所有的模板被定義

#define USE_CACHE_LRU 1 
#define USE_CACHE_FALRU 1 
#define USE_CACHE_IIC 1 

我不知道這個文件是如何編譯。如您所見,FALRUBlk::accessBlock()需要4個參數。但是在Cache::access()中,只傳遞了三個參數。 那麼有人可以解釋如何編譯這個函數沒有問題?

回答

3

它編譯罰款,因爲用於第4的默認值:

FALRUBlk* accessBlock(Addr addr, int &lat, int context_src, int *inCache = 0); 

其他2只3個參數:

IICTag* accessBlock(Addr addr, int &lat, int context_src); 
BlkType* accessBlock(Addr addr, int &lat, int context_src); 

因此,你可以隨時調用這個方法就像在你例如:

blk = tags->accessBlock(pkt->getAddr(), lat, id); 
+0

那麼不是「參數必須匹配」重要嗎? – mahmood 2012-01-18 17:40:54

+0

@mahmood當然參數必須匹配(否則你會得到一個編譯錯誤)。在第一種情況下,由於您通過傳遞3個值來調用它,所以'0'被自動分配給inCache變量)。 – 2012-01-18 17:42:43

+0

問題是,當我爲'BlkType * accessBlock'(現在需要四個參數)添加另一個參數時,編譯器說錯誤,無法將我的第四個參數轉換爲'int *'(這是'FALRUBlk *'的第四個參數) – mahmood 2012-01-18 17:43:01

0

在C++和大多數其他編程語言中,您可以設置def函數參數的一個值。特別是在C++中,您甚至可以爲您的模板化類提供默認模板參數。

一般規則是默認參數在最後。您必須將參數的默認參數放在參數列表中。你可以有任意數量的參數,默認參數 - 對於你所關心的,你的函數可以有10個參數,每個參數都有一個默認值。

如果是這種情況,可以在不傳遞任何參數的情況下調用10參數函數 - 因爲對於所有密集目的,函數的作用就像調用指定爲默認值的值一樣。

你用這個比你想象的要多。對於一個稍微複雜的例子,STL關聯容器(如std :: set)已經排序。他們提供std :: less <>的「默認模板參數」,表示「此容器中的項目必須使用它們的<運算符進行排序」。它們還爲定義其內存管理接口的分配器提供了另一個默認模板參數。

那些除非你決定通過「重寫」的默認參數改變它們完全隱藏你,這就是爲什麼你能夠創建一組只std::set<DataType>當真正的類型會是這樣看起來更像std::set<Key, Compare, Allocator<Key> >;