我认为我在所有编译器中都遇到了模板类型推断错误,但是在报告之前,我想确保自己没有错过任何内容。
考虑一个例子:
#include <utility>
template <std::size_t... I, typename... T>
void foo(std::index_sequence<I...>, decltype(I)..., T...) {}
int main()
{
foo(std::make_index_sequence<3>{}, 1, 2, 3, 4, 5);
}
decltype(I)
用于缩短MWE。
error: too few arguments to function
error: no matching function for call to 'foo'
error C3543: 'unknown-type': does not contain a parameter pack
崩溃我不明白为什么它不能扣除T
,特别是因为如果我用varargs替换参数包(除了MSVC,它又有ICE),它就可以工作。
template <std::size_t... I>
void foo(std::index_sequence<I...>, decltype(I)..., ...) {}
还有许多其他方法可以满足我的需求,但这是最短的方法,我看不出它应该失败的任何原因。
更新:用演绎法替代的已知有效示例是:
template <typename T>
struct type_identity
{ using type = T; };
template <typename T, typename... U>
void foo(T, typename type_identity<T>::type, U...) {}
int main()
{
foo(1, 2, 3, 4, 5);
}
更新#2 原始示例的修改后的版本不会使Clang崩溃,但是关于错误的注释却很奇怪note: candidate template ignored: deduced conflicting types for parameter 'T' (<int, int, int> vs. <>)
#include <utility>
template <typename T>
struct type_identity
{ using type = T; };
template <typename...>
struct type_pack {};
template <typename... T, typename... U>
void foo(type_pack<T...>, typename type_identity<T>::type..., U...) {}
int main()
{
foo(type_pack<int, int, int>{}, 1, 2, 3, 4, 5);
}
答案 0 :(得分:5)
我认为您的代码不符合标准,但是可以争论的是,应该更改标准以使其格式正确。
标准中对模板自变量推导过程的描述如下:
因此,过程是 substitution-deduction-substitution ;替换 deduced 自变量后,没有后续的推论。 [temp.deduct]/6为该视图提供了进一步的支持:
在模板自变量推导过程中的某些点,必须采用利用模板参数的函数类型,并将这些模板参数替换为相应的模板自变量。当将任何显式指定的模板参数替换为函数类型时,此操作在模板参数推论的开始时进行;当替换从默认参数推论或获得的任何模板参数时,在模板参数推论的末尾也是如此。
您的示例格式错误,因为需要先演绎然后进行替换然后演绎:除非首先{em}既推导并替代了T...
,否则才能推论I...
。