2012-01-18 92 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> >;