实例化函数模板时省略模板类型参数合法吗



以下代码实现了一个函数模板foo,它接受任意数量的参数,并随后处理每个参数,同时维护该参数的位置索引:

template<int index, typename T>
void foo_impl(T value)
{
// Do something with index/value
}
template<int index, typename T, typename... Rest>
void foo_impl(T value, Rest... values)
{
// Do something with index/value
// Recursively handle remaining arguments
foo_impl<index + 1>(values...);
}
template<typename... T>
void foo(T... args)
{
foo_impl<1>(args...);
}
int main()
{
foo("test", 42);
}

这递归地实例化函数模板,直到它到达接受单个参数的基模板。foo_impl的每个函数模板实例化都省略了模板类型参数。尽管这与Clang、GCC和MSVC一起编译,但我不确定这是否合法。

如代码示例所示,省略模板参数合法吗?如果是,具体规则是什么?这些规则在C++标准之间发生了变化吗?

具体规则在[temp.arg.extical]

3可以推导或获得的尾随模板参数from默认模板参数可以从显式模板参数。尾部模板参数包不是否则将推导为空的模板序列论点。如果所有的模板参数都可以推导出来,那么它们可能全部省略;在这种情况下,空模板参数列表<>也可以省略其本身。在进行演绎和失败,或者在没有进行推导的情况下,如果模板指定了参数列表,它以及任何默认模板参数,标识单个函数模板专用化,然后模板id是函数模板专用化的左值。

由于类型参数是尾随的,并且可以从函数调用的参数中推导出来,因此可以省略它们。

迄今为止,所有标准修订版中都存在这种措辞(除了关于参数包的部分,C++03中没有(。

最新更新