显式指定的模板参数包

Explicitly-specified template parameter packs

比方说,我有以下代码:

#include <iostream>

template <size_t... Is> struct E {};

template <typename... Ts, size_t... Is>
void func (E<Is...>, Ts...) {std::cout << __PRETTY_FUNCTION__ << std::endl;}

int main()
{
    func(E<1,2,3>{}, 1, 'a');
}

它工作得很好并产生

void func(E<Is ...>, Ts ...) [with Ts = {int, char}; long unsigned int ...Is = {1, 2, 3}]

但是,如果我将 func 调用替换为 func<int, char, 1, 2, 3>(E<1,2,3>{}, 1, 'a');,则会导致编译错误,即

template argument deduction/substitution failed

为什么编译器禁止显式指定多个参数包?

这遵循模板参数推导规则。

当你显式指定func的模板参数时,编译器会贪心匹配第一个参数包。编译器不会弄清楚,一旦您开始将 int 放入参数中,它就应该开始替换 Is...

相反,它将继续替换 Ts...,您将收到一条错误消息:

expected a type, but got 1

对于第三个明确指定的参数。

如果你指定 只有 Ts... 就可以看到这个,像这样:

func<int, char>(E<1,2,3>{}, 1, 'a');

编译得很好。