有一个有三个模板的课程。
#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()
中,只传递了三个参数。
那么有人可以解释这个函数如何编译没有问题吗?
答案 0 :(得分: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);
答案 1 :(得分:0)
在C ++和大多数其他编程语言中,您可以为函数的参数设置默认值。特别是在C ++中,您甚至可以为模板化类提供默认模板参数。
一般规则是默认参数在最后。您必须在参数列表中最后放置带有默认参数的参数。你可以使用默认参数获得任意数量的参数 - 对于你所关心的,你的函数可以有10个参数,每个参数都有一个默认值。
如果是这种情况,可以在不传递任何声明的情况下调用您的10参数函数 - 因为对于所有密集目的,该函数将像使用指定为默认值的值调用它一样。
你比你想象的更多地使用它。对于稍微复杂的示例,STL关联容器(如std :: set)具有排序。它们提供了std :: less&lt;&gt;的“默认模板参数”。说“必须使用&lt; operator”对此容器中的项进行排序。它们还为分配器提供了另一个默认模板参数,用于定义其内存管理接口。
除非您决定通过“覆盖”默认参数来更改它们,否则这些对您完全隐藏。这就是为什么当真实类型看起来像某个东西时你能够创建一个只有std::set<DataType>
的集合的原因更像是std::set<Key, Compare, Allocator<Key> >;
。