具有不同数量参数的模板函数

template functions with different number of arguments

本文关键字:函数 参数      更新时间:2023-10-16

有一个类有三个模板。

#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);

正如您所看到的,其中一个模板的参数数量与其他模板不同。

现在在Cache()中,有一个函数调用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()中,只传递了三个参数。那么,有人能解释一下这个函数是如何编译的吗?

它编译得很好,因为使用了第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);

在C++和大多数其他编程语言中,允许为函数的参数设置默认值。特别是在C++中,您甚至可以为模板化的类提供默认的模板参数。

一般规则是,默认的参数在末尾。必须将具有默认参数的参数放在参数列表的最后。你可以有任意数量的带有默认参数的参数——不管你怎么说,你的函数可以有10个参数,每个参数都有一个默认值。

如果是这样的话,可以在不传入任何aguments的情况下调用您的10参数函数,因为出于所有密集目的,该函数的行为就像您使用指定为默认值的值来调用它一样。

你使用这个比你想象的要多。对于稍微复杂一点的示例,STL关联容器(如std::set)具有排序。它们提供std::less<>的"默认模板参数"表示"此容器中的项目必须使用其<运算符进行排序"。它们还为分配器提供了另一个默认模板参数,该参数定义了它们的内存管理接口。

除非您决定通过"覆盖"默认参数来更改它们,否则这些参数将对您完全隐藏。,这就是为什么当真正的类型看起来更像std::set<Key, Compare, Allocator<Key> >;时,你可以创建一个只有std::set<DataType>的集合。