G++ rejects this explicit instantiation definition as ambiguous: template<typename T> struct S { void foo(int) { } template<typename U> void foo(U) { } }; template void S<char>::foo(int); // XXX EDG thinks it's OK, clang crashes, and G++ says: inst.cc:8:15: error: ambiguous template specialization ‘foo<>’ for ‘void S<char>::foo(int)’ template void S<char>::foo(int); // XXX ^ inst.cc:4:8: note: candidates are: void S<T>::foo(int) [with T = char] void foo(int) { } ^ inst.cc:5:29: note: template<class U> void S<T>::foo(U) [with U = U; T = char] template<typename U> void foo(U) { } ^ I think EDG is correct and the diagnostic is wrong, because I'm not referring to any foo<> but rather foo. Changing the instantiation to be unambiguously a template produces almost the same error (with foo<> replaced by foo<int>) and that definitely isn't ambiguous because one candidate isn't even a function template: template<typename T> struct S { void foo(int) { } template<typename U> void foo(U) { } }; template void S<char>::foo<int>(int); // XXX inst.cc:8:15: error: ambiguous template specialization ‘foo<int>’ for ‘void S<char>::foo(int)’ template void S<char>::foo<int>(int); // XXX ^ inst.cc:4:8: note: candidates are: void S<T>::foo(int) [with T = char] void foo(int) { } ^ inst.cc:5:29: note: template<class U> void S<T>::foo(U) [with U = U; T = char] template<typename U> void foo(U) { } ^
Apparently EDG instantiates the member function template, which is not what I wanted: template<typename T> struct S { void foo(int) { } template<typename U> void foo(U); // undefined }; template void S<char>::foo(int); // XXX "inst.cc", line 8: error: function "S<T>::foo(U) [with T=char, U=int]" cannot be instantiated -- no template definition was supplied template void S<char>::foo(int); // XXX ^ Is there no syntax for instantiating the non-template?
At http://llvm.org/bugs/show_bug.cgi?id=21661 Richard identified this as http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1665
The current handling of the following is still wrong (rejects-valid) independent of DR 1665. It should compile because it can only refer to the template: template<typename T> struct S { void foo(int); template<typename U> void foo(U) { } }; template void S<char>::foo<>(int);
*** Bug 55136 has been marked as a duplicate of this bug. ***
Dup of bug 39270. *** This bug has been marked as a duplicate of bug 39270 ***
Reopening.
*** Bug 104204 has been marked as a duplicate of this bug. ***