Nik*_*zev 8 c++ language-lawyer variadic-templates template-argument-deduction c++14
我想我在所有编译器中遇到了模板类型演绎错误,但在报告之前我想确定我没有错过任何东西.
考虑一个例子:
#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);
}
Run Code Online (Sandbox Code Playgroud)
decltype(I) 这里用来缩短MWE.
error: too few arguments to functionerror: 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)..., ...) {}
Run Code Online (Sandbox Code Playgroud)
还有很多其他方法可以制作我想要的东西,但这是最短的方式,我没有看到它应该失败的任何理由.
更新:在deducible上替换的已知有效示例是:
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);
}
Run Code Online (Sandbox Code Playgroud)
更新#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);
}
Run Code Online (Sandbox Code Playgroud)
我认为你的代码在标准中是不正确的,但可以提出一个论点,即应该改变标准以使其格式良好.
模板参数推导过程在标准中描述如下:
因此,程序是替代 - 扣除 - 替代 ; 在替换推导出的论点后,没有后续的推论.[temp.deduct]/6提供了对此视图的进一步支持:
在模板参数推导过程中的某些点,有必要采用一个使用模板参数的函数类型,并用相应的模板参数替换这些模板参数.当任何显式指定的模板参数被替换为函数类型时,这在模板参数推导的开始处完成,并且当替换从默认参数推导或获得的任何模板参数时,再次在模板参数推断的结尾处完成.
你的例子是不正确的,因为它需要扣除然后替换然后扣除:T...除非I...先推断和替换,否则不能推断.
| 归档时间: |
|
| 查看次数: |
287 次 |
| 最近记录: |