模板参数包的错误推导
incorrect deduction of template parameter pack
以下程序无法编译:
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
test<2, 3, true, false>(2, 1, {8, 8});
}
看到了live on Coliru.
错误信息
g++ -std=c++17 -O1 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:8:41: error: too many arguments to function 'void test(ParametersType&& ...)
[with unsigned int dim = 2; unsigned int N = 3; bool P = true; bool C = false; ParametersType = {}]'
8 | test<2, 3, true, false>(2, 1, {8, 8});
| ^
main.cpp:2:6: note: declared here
2 | void test(ParametersType&&... par)
| ^~~~
表示参数包ParametersType...
推导为空,而我希望它根据传递给test
的参数类型推导。
问题出在传递给 test
的 {8, 8}
参数中。
显式传递一个 std::array
给函数解决问题:
#include <array>
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
test<2, 3, true, false>(2, 1, std::array<int, 2>{8, 8});
}
看到了live on Coliru.
为什么编译器在第一个示例中明显错误地推断出包?
如果编译器无法将 {8, 8}
推断为 std::array
,我预计会出现 "impossible to deduce" 错误。为什么编译器将包推断为空包?
模板错误很难改正。这只是实施的质量。实例的 Clang 给出
main.cpp:2:6: note: candidate template ignored: substitution failure
[with dim = 2, N = 3, P = true, C = false]: deduced incomplete pack <int, int, (no value)>
for template parameter 'ParametersType'
哪个更容易理解。是的,除非使用 auto
、.
来自cppreference:
A braced-init-list is not an expression and therefore has no type,
e.g. decltype({1,2}) is ill-formed. Having no type implies that
template type deduction cannot deduce a type that matches a
braced-init-list, so given the declaration template void
f(T); the expression f({1,2,3}) is ill-formed.
您也可以在这种情况下使用 auto
来解决您的问题:
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
auto x = { 8, 8 };
test<2, 3, true, false>(2, 1, x);
}
以下程序无法编译:
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
test<2, 3, true, false>(2, 1, {8, 8});
}
看到了live on Coliru.
错误信息
g++ -std=c++17 -O1 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:8:41: error: too many arguments to function 'void test(ParametersType&& ...)
[with unsigned int dim = 2; unsigned int N = 3; bool P = true; bool C = false; ParametersType = {}]'
8 | test<2, 3, true, false>(2, 1, {8, 8});
| ^
main.cpp:2:6: note: declared here
2 | void test(ParametersType&&... par)
| ^~~~
表示参数包ParametersType...
推导为空,而我希望它根据传递给test
的参数类型推导。
问题出在传递给 test
的 {8, 8}
参数中。
显式传递一个 std::array
给函数解决问题:
#include <array>
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
test<2, 3, true, false>(2, 1, std::array<int, 2>{8, 8});
}
看到了live on Coliru.
为什么编译器在第一个示例中明显错误地推断出包?
如果编译器无法将 {8, 8}
推断为 std::array
,我预计会出现 "impossible to deduce" 错误。为什么编译器将包推断为空包?
模板错误很难改正。这只是实施的质量。实例的 Clang 给出
main.cpp:2:6: note: candidate template ignored: substitution failure
[with dim = 2, N = 3, P = true, C = false]: deduced incomplete pack <int, int, (no value)>
for template parameter 'ParametersType'
哪个更容易理解。是的,除非使用 auto
、
来自cppreference:
A braced-init-list is not an expression and therefore has no type, e.g. decltype({1,2}) is ill-formed. Having no type implies that template type deduction cannot deduce a type that matches a braced-init-list, so given the declaration template void f(T); the expression f({1,2,3}) is ill-formed.
您也可以在这种情况下使用 auto
来解决您的问题:
template <unsigned int dim, unsigned int N, bool P, bool C, class... ParametersType>
void test(ParametersType&&... par)
{
}
int main()
{
auto x = { 8, 8 };
test<2, 3, true, false>(2, 1, x);
}