Consider the following example:
namespace N {
template<class>
struct C { };
template<int, class T>
void foo(C<T>);
}
template<class T>
void bar(N::C<T> c) {
foo<0>(c);
}
int main() {
N::C<void> c;
bar(c);
}
Both GCC and Clang fail to compile this code under C++17 standard (with -Werror
), because (according to my understanding) in C++17 ADL doesn't work when explicit template arguments <...>
are present (unless a name is already established as a template name), so foo
is a non-dependent name that is not found.
In C++20, the ADL rules have changes, and explicit template arguments don't prevent ADL. Now it seems that foo
becomes a dependent name that should be resolvable via ADL. However, GCC and Clang have different opinions about the validity of this code. CLang compiles it without errors, but GCC (10.2, -std=c++2a
) complains:
error: 'foo' was not declared in this scope; did you mean 'N::foo'?
In C++17 mode, Clang produces the following warning:
warning: use of function template name with no prior declaration in function call with explicit template arguments is a C++20 extension
Demo.
I have three related questions:
- Which compiler is right and why?
- In C++17, is
foo
infoo<0>(c)
considered as a dependent name? - In C++20, is
foo
infoo<0>(c)
considered as a dependent name?