G++ и clang++ различное поведение, определяющее различные значения шаблона auto - программирование
Подтвердить что ты не робот

G++ и clang++ различное поведение, определяющее различные значения шаблона auto

Другой "кто прямо между g++ и кланом g++?"

На этот раз я убежден, что это ошибка g++, но я прошу подтверждения у стандартных гуру.

Учитывая следующий код

template <template <auto...> class Cnt,
          typename ... Types,
          Types ... Vals>
void foo (Cnt<Vals...>)
 { }

template <auto ...>
struct bar
 { };

int main ()
 {
   foo(bar<0, 1>{});  // compile both
   foo(bar<0, 1L>{}); // only clang++ compile; error from g++
 }

Живая демоверсия

клан g++ (8.0.0, пример) компилирует и связывает без проблем, где g++ (9.2.0, пример) дает следующую ошибку, компилируя второй foo() (но не первый) вызов

prog.cc: In function 'int main()':
prog.cc:16:20: error: no matching function for call to 'foo(bar<0, 1>)'
   16 |    foo(bar<0, 1L>{}); // only clang++ compile; error from g++
      |                    ^
prog.cc:6:6: note: candidate: 'template<template<auto ...<anonymous> > class Cnt, class ... Types, Types ...Vals> void foo(Cnt<Vals ...>)'
    6 | void foo (Cnt<Vals...>)
      |      ^~~
prog.cc:6:6: note:   template argument deduction/substitution failed:
prog.cc:16:20: note:   mismatched types 'int' and 'long int'
   16 |    foo(bar<0, 1L>{}); // only clang++ compile; error from g++
      |                    ^
prog.cc:16:20: note:   'bar<0, 1>' is not derived from 'Cnt<Vals ...>'

Если я правильно понимаю, g++ требуют, чтобы Types... Vals... совпадали, когда клан g++ признает, что Vals... имеют разные Types....

Кто прав?

- ОБНОВЛЕНИЕ -

Как указал Марек Р. (спасибо), MSVC (v19.22) также не удалось скомпилировать.

Но, если я правильно понимаю, не удалось также скомпилировать первый вызов foo() со следующей ошибкой

<source>(13): error C2672: 'foo': no matching overloaded function found
<source>(13): error C2893: Failed to specialize function template 'void foo(Cnt<Vals...>)'
<source>(13): note: With the following template arguments:
<source>(13): note: 'Cnt=bar'
<source>(13): note: 'Types={}'
<source>(13): note: 'Vals={0, 1}'

- ОБНОВЛЕНИЕ 2 -

camp0 отмечает (спасибо), что g++ компилирует этот код до версии 7.4.

Ошибка, представленная в 8.1, или ошибка в моем коде и g++ исправили его код из 8.1?

4b9b3361

Ответ 1

Ни один из трех компиляторов не является правильным.

С [temp.param]/17:

Если параметр шаблона представляет собой параметр типа с многоточием перед его необязательным идентификатором или является объявлением параметра, которое объявляет пакет ([dcl.fct]), то параметр шаблона является пакетом параметров шаблона. Пакет параметров шаблона, который является объявлением параметра, тип которого содержит один или несколько нерасширенных пакетов, является расширением пакета.... Пакет параметров шаблона, который является расширением пакета, не должен расширять пакет параметров шаблона, объявленный в том же списке параметров шаблона. [Пример:

...

template <class... T, T... Values>              // error: Values expands template type parameter
  struct static_array;                          // pack T within the same template parameter list

— end example ]

Таким образом, код некорректен даже без строки foo(bar<0, 1L>{});.

Уже есть отчет об ошибках Clang и отчет об ошибках GaC bug report.