模板参数包的不正确推导

问题描述 投票:0回答:2

以下程序无法编译:

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的参数的类型推导。

问题出在传递给{8, 8}test参数中。显式传递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,则可能会出现“无法推论”错误。为什么相反,编译器将包推导出为空?]

c++ variadic-templates template-argument-deduction
2个回答
3
投票

模板错误很难纠正。这只是实现的质量。实例的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{stuff} has no type


0
投票

来自{stuff}

braced-init-list不是表达式,因此具有no type,例如decltype({1,2})格式错误。没有类型意味着模板类型推导无法推导与braced-init-list,因此给定声明模板无效f(T);表达式f({1,2,3})的格式不正确。

您也可以在这种情况下使用cppreference解决您的问题:

auto
© www.soinside.com 2019 - 2024. All rights reserved.