The following code snippet declares a friend function template and defines one specialization outside of the class:
class A {
template<typename T>
friend T f();
};
template <>
int f<int>() {
return 0;
}
clang 16.0 compiles it but g++ 13.1 rejects it with
error: 'f' is not a function template
(Both compiled with -pedantic -std=c++2a
; g++ does compile it if the template is declared again outside of the class; clang rejects it with int main() { f<int>(); }
.)
Which compiler is standard compliant in this case?
As I understand it, names that are introduced by friend
declarations in classes are not visible during normal name lookup. Therefore I'd guess g++ is correct -- although I'm curious whether providing specializations alone (without calling f
) is valid as per the standard.
GCC is correct: this is ill-formed. This is basically CWG2261, which has been closed as Not A Defect since P1787 clarified that ordinary lookup is employed to find the function template being instantiated (or, here, specialized) even though it is not performed for ordinary declarations like
void f();