This code: template<class C> class S { public: S(); private: }; class T { friend S<int>::S<int>(); public: T(); private: void f() const; }; template<class C> S<C>::S() { // T t; t.f(); } S<int> s; Compiled with this command line: c++ -c test02.cxx Gives this error test02.cxx:8: no `void S<int>::S()' member function declared in class `S<int>' Release: 3.0.2 Environment: System: Linux jsberg1 2.4.9 #2 SMP Tue Aug 21 17:36:52 EDT 2001 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ../gcc-3.0.2/configure --prefix=/opt/gcc-3.0.2
Fix: Plenty of workarounds: friend class S<int>; or template<class C> friend S<C>::S();
State-Changed-From-To: open->analyzed State-Changed-Why: Confirmed.
From: "Giovanni Bajo" <giovannibajo@libero.it> To: <gcc-gnats@gcc.gnu.org>, <gcc-bugs@gcc.gnu.org>, <nobody@gcc.gnu.org>, <gcc-prs@gcc.gnu.org>, <jsberg@bnl.gov> Cc: Subject: Re: c++/5023: [2003-01-13]Error declaring constructor of template class specialization as friend Date: Fri, 4 Apr 2003 19:52:01 +0200 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p r=5023 Basically, it's just this: --------------------------- template<class C> struct S { S(); }; struct T { friend S<int>::S<int>(); }; ---------------------------- pr5023.cpp:7: error: no `void S<int>::S()' member function declared in class ` S<int>' Reconfirmed with 2.95, 3.2, and 3.3 20030401 Giovanni Bajo
Hmm, I do not know if this is really valid as ICC 6.0 rejects this: pr5023.cc pr5023.cc(8): error: overloaded function "S<C>::S [with C=int]" is not a template friend S<int>::S<int>(); ^ pr5023.cc(8): warning #880: omission of explicit type is nonstandard ("int" assumed) friend S<int>::S<int>(); ^ compilation aborted for pr5023.cc (code 2) But this is valid and is rejected by gcc but accpected by ICC: template<class C> struct S { S(); }; struct T { friend S<int>::S(); };
I think this is related to bug 9050.
(In reply to comment #4) > But this is valid and is rejected by gcc but accpected by ICC: This is now accepted on the trunk. friend S<int>::S<int>(); is still rejected but I don't know if that is valid or not.
friend S<int>::S<int>() is not valid; S<int>::S names the constructor, which is not a template. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#147