非类型参数的非推导上下文

Non Deduced context for a non type parameter

我正在阅读 C++ 模板(第 2 版),这是书中的一个片段:

template<typename... Ts, int N>
void f(double (&)[N+1], Ts... ps) {return;}

书上明确指出上面的声明是无用的,因为N不能指定也不能推导

我试图理解为什么像下面这样的东西是错误的:

double arr[2];
f<int, double, 1>(arr, 1, 2.0);

当我编译上面的代码片段时,出现错误,没有匹配的函数来调用 f。

这个编译很好

template<typename... Ts, typename T> 

void func(T value){}; 
func(1); 

尽管我在参数包后面有一个额外的参数。

为什么我指定的模板参数与提供的参数明显不匹配?请帮助我理解这一点。

N无法推导与参数包无关。这也不会编译,因为无法推导出 N。

template<int N>
void f(double (&)[N+1]) {}

int main() {
    double arr[2];
    f(arr);
}

来自 cppreference(非推导上下文):

In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
[...]
3) A non-type template argument or an array bound in which a subexpression references a template parameter

无法指定 N 的事实有不同的原因:标准说您不能简单地指定放置在参数包之后的参数。

来自 [temp.param]:

A 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 of the function template or has a default argument (14.8.2). [Example:

template<class T1 = int, class T2> class B;    // error

// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { }  // error
template<class... T, class U> void g() { }     // error

—end example ]

(参见 我从中得到的报价)

您的另一个示例有效,因为 T 可以从参数中推导出来。

template<typename... Ts, typename T> 
void func(T value){}; 
func(1); // 1 is used to deduce T