Другой, кто прямо между g++ и clang++? вопрос для стандартных гуру С++.
Код следующий
template <typename ...>
struct bar
{ };
template <typename ... Ts>
void foo (bar<Ts...> const &)
{ }
int main ()
{
foo<int>(bar<int, long>{}); // g++ and clang++ compile
(*(&foo<int>))(bar<int, long>{}); // g++ and clang++ give error
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
}
Функция шаблона foo()
принимает параметр вариационного шаблона bar
.
Первый вызов
foo<int>(bar<int, long>{}); // g++ and clang++ compile
работает как для clang++ ang g++.
Если я правильно понял, foo<int>
высвечивается только первый параметр шаблона, и это не завершает список параметров Ts...
. Таким образом, компилятор просматривает аргумент (объект bar<int, long>
) и выводит полный список.
Второй вызов отличается
(*(&foo<int>))(bar<int, long>{}); // g++ and clang++ give error
Если я правильно понимаю, с (&foo<int>)
мы получаем указатель на экземпляр foo
, где Ts...
- это точно int
(не только первый тип списка, но и весь список) и разыменовывая его (< *(&foo<int>)
) и вызывая его с неправильным аргументом (объект bar<int, long>
), мы получаем (clang++ и g++) ошибку компиляции.
До сих пор так хорошо.
Проблема возникает при третьем вызове
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
что я был убежден (может быть, я был неправ) эквивалентен второй (мы фиксируем все типы шаблонов в Ts...
, тогда мы вызываем функцию с неправильным параметром), но g++ кажется соглашающимся (и дает ошибку), где clang++ не согласен (и скомпилировать без проблем).
Вопрос, как обычно, таков: кто прав?