Типы классов C ++ в не типовых параметрах шаблона: ошибка руководства по выводу - PullRequest
1 голос
/ 23 января 2020

Проблема

Я использую функцию c ++ 2a, которая допускает использование struct / std :: array в качестве аргументов шаблона (g++-9.2.0, пока не поддерживается в clang). Функция называется Class types in non-type template parameters и предлагается в P0732R2.

. Я пытаюсь использовать параметры шаблонов одного класса (struct C в примерах ниже), чтобы вывести соответствующие параметры шаблона класса для второго класс (struct B в примерах ниже). Настоящим я использую руководство по выводу параметров шаблона класса, которое я написал для этой конкретной цели c.

В этом минимальном примере информацию, которую я хочу извлечь, составляют два int s. Если я использую эти примитивные типы в качестве параметров шаблона, все работает нормально. Однако, когда я объединяю информацию в один std::pair или пользовательский std::struct, вычет не выполняется.

Код

Отдельная информация

Код ниже работает просто отлично .

#include <array>

/// Data structure which contains a constexpr context to be used for type deduction later
template <int aa, int ab> struct C {};

/// Class which has to find out its own type
template <std::size_t count, std::array<int, count> a, std::array<int, count> b> struct B {
  template <int... aa, int... bb> explicit B(C<aa, bb> ... c) {}
};

/// Class deduction guide
template <int... aa, int... ab> B(C<aa, ab>... c)
    ->B<sizeof...(aa) + 1, std::array<int, sizeof...(aa) + 1>{aa...},
        std::array<int, sizeof...(aa) + 1>{ab...}>;

int main() { B k{C<1, 2>{}, C<2, 3>{}}; }

Объединенная информация

Приведенный ниже код не может быть скомпилирован.

#include <array>

/// Change: A contains the information from the previous example in a structs.
struct A { int a; int b; };

/// Data structure which contains a constexpr context to be used for type deduction later
template <A a> struct C {};

/// Class which has to find out its own type
template <std::size_t count, std::array<A, count> a> struct B {
  template <A... af> explicit B(C<af> ... c) {}
};

/// Class deduction guide
template <A... af> B(C<af>... c)->B<sizeof...(af) + 1, std::array<A, sizeof...(af) + 1>{af...}>;

int main() { B k{C<A{1, 2}>{}, C<A{2, 3}>{}}; }

Вывод ошибки:


main.cc: In function ‘int main()’:
main.cc:24:14: error: class template argument deduction failed:
   24 |   B k {c1, c2};
      |              ^
main.cc:24:14: error: no matching function for call to ‘B(C<A{1, 2}>&, C<A{1, 2}>&)’
main.cc:17:20: note: candidate: ‘B(C<((const A)af)>...)-> B<(sizeof... (af) + 1), std::array<A, (sizeof... (af) + 1)>{(const A)af ...}> [with A ...af = {}]’
   17 | template <A... af> B(C<af>... c)->B<sizeof...(af) + 1, std::array<A, sizeof...(af) + 1>{af...}>;
      |                    ^
main.cc:17:20: note:   candidate expects 0 arguments, 2 provided
main.cc:14:31: note: candidate: ‘template<long unsigned int count, std::array<A, count> a, A ...af> B(C<((const A)af)>...)-> B<count, a>’
   14 |   template <A... af> explicit B(C<af> ... c) {}
      |                               ^
main.cc:14:31: note:   template argument deduction/substitution failed:
main.cc:24:14: note:   couldn’t deduce template parameter ‘count’
   24 |   B k {c1, c2};

Мне сейчас интересно что вызывает эту проблему. Ошибка возникает из-за того, что

  • ... то, чего я хочу достичь, вообще невозможно,
  • ... что-то еще не реализовано в g ++
  • . .. Я облажался с моим руководством вывода?

Я также не понимаю сообщение об ошибке. Похоже, что для функции ожидаются нулевые аргументы. Проблема в том, что C<af>... нельзя развернуть в конструкторе?

1 Ответ

0 голосов
/ 23 января 2020

@ AndiG и @walnut ответили на мой вопрос со своими комментариями к моему первоначальному вопросу.

Возможно, моя проблема вызвана ошибкой в ​​моей версии G++-9. В настоящее время я не использую новейшую версию g++-9, ошибка решена, по крайней мере, в g ++ - 10. В версии g++-10.0, которую я скомпилировал (3684bbb022c), я больше не получаю сообщение об ошибке.

...