函数模板参数包后跟模板参数和特化

Function template parameter pack followed by template parameter and specialisation

在函数模板的定义中使用的模板参数包是否可以在定义时跟随另一个模板参数,当该参数仅被赋予其所需的默认值时;而不是声明?考虑以下示例:

template <typename ...Ts, typename T>
auto sz(Ts...);

template <typename ...Ts, typename T = int>
auto sz(Ts...) { return sizeof...(Ts); }

我发现GCC和Clang不同意这一点(GCC给出编译错误)。

-- 编辑 -- 在最初的误解后更正。

我想 g++ 是对的,clang++ 是错的。

根据C++17标准,17.1.11,

template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list (11.3.5) of the function template or has a default argument (17.8.2).

因此,在可变参数包之后应该接受具有默认值的模板参数。

问题是:我们只能在函数声明中或函数定义中(与函数声明不同时)设置模板默认值?

事实上,您可以简单地使用

来简化您的问题
template <typename>
void foo ();

template <typename = int>
void foo ()
 { }

int main ()
 {
   foo();
 }

被 clang++ 接受,被 g++ 拒绝。

这对我来说不是很清楚,但是我在 17.1.9 中阅读了

A default template-argument may be specified in a template declaration. A default template-argument shall not be specified in the template-parameter-list s of the definition of a member of a class template that appears outside of the member’s class. A default template-argument shall not be specified in a friend class template declaration. If a friend function template declaration specifies a default template-argument , that declaration shall be a definition and shall be the only declaration of the function template in the translation unit

此片段明确表示 "A default template-argument may be specified in a template declaration"。不在 "definition".

排除那个"A default template-argument shall not be specified in the template-parameter-list s of the definition of a member of a class template that appears outside of the member’s class",所以我初步断定一个模板泛型函数可以在"definition"中指定默认的template-argument,但是这部分是关于一个"class template",所以template-argument 是关于 class,而不是关于成员。

正如 sigma(谢谢!)在 17.1.10 中指出的那样,我们可以阅读

The set of default template-argument s available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are

同样:"declarations" 没有 "definition"。

所以我认为 clang++ 是错误的而 g++ 是正确的。