Another "who's right between g++ and clang++ ?" question for C++ standard gurus.
The code is the following
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
}
The template function foo()
receive a variadic template parameter bar
.
The first call
foo<int>(bar<int, long>{}); // g++ and clang++ compile
works for both clang++ ang g++.
If I understand correctly, with foo<int>
is explicated only the first template parameter and this doesn't complete the list of Ts...
parameters. So the compiler look at the argument (a bar<int, long>
object) and deduce the full list.
The second call is different
(*(&foo<int>))(bar<int, long>{}); // g++ and clang++ give error
If I understand correctly, with (&foo<int>)
we get the pointer to the instantiation of foo
where Ts...
is exactly int
(not only the first type of the list but the whole list) and dereferencing it (*(&foo<int>)
) and calling it with a wrong argument (a bar<int, long>
object) we get (clang++ and g++) a compilation error.
So far, so good.
The problem arises with the third call
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
that I was convinced (maybe I was wrong) equivalent the second one (we fix all template types in Ts...
, then we call the function with a wrong parameter) but g++ seems agree (and gives error) where clang++ disagree (and compile without problem).
The question, as usual, is: who's right ?