In this program, Beta::Gamma declares ::Alpha as a friend, but the friendship does not work. === mec@hollerith:~/exp-friend$ cat z1.cc template <typename T> void Alpha(T* a) { a->Delta(); } namespace Beta { class Gamma { public: template <typename T> friend void ::Alpha(T*); private: void Delta(); }; } int main() { Beta::Gamma* a = new Beta::Gamma; ::Alpha(a); } bash: /home/mec/gcc-4.2.1/install/bing++: No such file or directory mec@hollerith:~/exp-friend$ /home/mec/gcc-4.2.1/install/bin/g++ -O2 -Wall -c z1.cc z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]': z1.cc:18: instantiated from here z1.cc:11: error: 'void Beta::Gamma::Delta()' is private z1.cc:2: error: within this context mec@hollerith:~/exp-friend$ /home/mec/gcc-4.2.2/install/bin/g++ -O2 -Wall -c z1.cc z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]': z1.cc:18: instantiated from here z1.cc:11: error: 'void Beta::Gamma::Delta()' is private z1.cc:2: error: within this context mec@hollerith:~/exp-friend$ /home/mec/gcc-4.3.0/install/bin/g++ -O2 -Wall -c z1.cc z1.cc: In function 'void Alpha(T*) [with T = Beta::Gamma]': z1.cc:18: instantiated from here z1.cc:11: error: 'void Beta::Gamma::Delta()' is private z1.cc:2: error: within this context mec@hollerith:~/exp-friend$ === In this program, Beta::Gamma declares the specialization ::Alpha<Beta::Gamma> as a friend. This works. ec@hollerith:~/exp-friend$ cat z3.cc template <typename T> void Alpha(T* a) { a->Delta(); } namespace Beta { class Gamma { public: friend void ::Alpha<Beta::Gamma>(Beta::Gamma*); private: void Delta(); }; } int main() { Beta::Gamma* a = new Beta::Gamma; ::Alpha(a); } mec@hollerith:~/exp-friend$ /home/mec/gcc-4.2.1/install/bin/g++ -O2 -Wall -c z3.cc mec@hollerith:~/exp-friend$ /home/mec/gcc-4.2.2/install/bin/g++ -O2 -Wall -c z3.cc mec@hollerith:~/exp-friend$ /home/mec/gcc-4.3.0/install/bin/g++ -O2 -Wall -c z3.cc mec@hollerith:~/exp-friend$ === I think z1.cc is valid, per this clause from [temp.friend]: "A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated (14.7.1), partially specialized (14.5.4) or explicitly specialized (14.7.3) are friends of the class containing the template friend declaration. I suspect it's a bug with the namespace part of "template <typename T> friend void ::Alpha(T*);".
I too believe that z1.cc is valid. icc accepts it. Not a regression, the code fails back to 2.95. W.
Fixed in 4.6.0.