http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17122
--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-04-12 14:07:00 UTC --- > pr17122.C:17:33: warning: friend declaration ‘void operator-(int, foo<blah>)’ > declares a non-template function [-Wnon-template-friend] > friend void operator-(int, foo);//eliminating <> generates warning to add > ^ > pr17122.C:17:33: note: (if this is not what you intended, make sure the > function template has already been declared and add <> after the function name > here) > friend void operator-(int, foo);//eliminating <> generates warning to add > ^ Well at least this warning is correct. For operator- it's 100% correct. It causes a problem for operator+ because that clashes with the name of a member function, so the hint is right but not sufficient to tell you how to make the code compile, because there's still another error. You also need to prevent name lookup from finding the member with the same name. The example can be reduced to this, replacing operators with named functions: template <class blah> struct foo; template <class blah> void f(int, foo<blah>) { } template <class blah> void g(int, foo<blah>) { } template <class blah> struct foo { void f(int) {} friend void f<>(int, foo); friend void g(int, foo); }; The warning about 'g' is correct. The error for 'f' is different now, giving the "declared void" instead of "as non-function"