неправильный вывод пакета параметров шаблона - PullRequest
1 голос
/ 20 апреля 2020

Следующая программа не компилируется:

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 на 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});
}

Посмотрите на это в прямом эфире на Coliru .

Почему компилятор, по-видимому, неправильно выводит пакет в первый пример?

Если компилятор не может вывести {8, 8} в std::array, я бы ожидал ошибку "невозможно вывести". Почему вместо этого компилятор выводит пакет в пустой?

Ответы [ 2 ]

3 голосов
/ 20 апреля 2020

Ошибки шаблона трудно исправить. Это просто качество реализации. 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} не имеет типа .

1 голос
/ 20 апреля 2020

С cppreference :

Список фигурных скобок не является выражением и поэтому имеет без типа , например, decltype ({1,2 }) плохо сформирован. Отсутствие типа подразумевает, что дедукция типа шаблона не может вывести тип, который совпадает со списком фигурных скобок, поэтому, учитывая шаблон объявления void f (T); выражение f ({1,2,3}) неправильно сформировано.

Вы также можете использовать 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);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...