The following fails to compile. Workaround is to declare forward reference to class outside the template. template<class Info> class Table { public: bool Lookup(int name, class Detail* detail, Info* info) const; void Insert(int name, class Detail* detail, Info info); }; class Detail { public: int stuff; }; template<class Info> bool Table<Info>::Lookup(int name, Detail* detail, Info* info) const { return true; } template<class Info> void Table<Info>::Insert(int name, Detail* detail, Info info) { } Release: g++ 3.2 Environment: RedHat 7.2, i686 multiprocessor
State-Changed-From-To: open->analyzed State-Changed-Why: Confirmed. Here's a simpler testcase: -------------------------- template <typename T> struct C { void foo (struct X *); }; struct X {}; template <typename T> void C<T>::foo(struct X *) {} ------------------------------- It's rejected by all versions of gcc. However, if one makes C a non-template, then it is accepted. Strange. I suspect that the language actually mandates this behavior, since both icc and cxx (well, both EDG based after all) have this behavior as well. I don't know what is right in this case. W.
This should be allowed according to DR433.
Patch for PR4403 also includes a fix to this bug (the while-loop hunk in pushtag).
Patch submitted: http://gcc.gnu.org/ml/gcc-patches/2005-03/msg01294.html
Subject: Bug 9783 CVSROOT: /cvs/gcc Module name: gcc Changes by: lerdsuwa@gcc.gnu.org 2005-03-14 14:51:25 Modified files: gcc/cp : ChangeLog name-lookup.c pt.c gcc/testsuite : ChangeLog gcc/testsuite/g++.old-deja/g++.pt: inherit2.C Added files: gcc/testsuite/g++.dg/template: friend34.C friend35.C Log message: PR c++/4403 PR c++/9783, DR433 * name-lookup.c (pushtag): Skip template parameter scope when scope is ts_global. Don't push tag into template parameter scope. * pt.c (instantiate_class_template): Reorder friend class template substitution to handle non-dependent friend class that hasn't been previously declared. * g++.dg/template/friend34.C: New test. * g++.dg/template/friend35.C: Likewise. * g++.old-deja/g++.pt/inherit2.C: Remove XFAIL's. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4662&r2=1.4663 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.112&r2=1.113 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.983&r2=1.984 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5161&r2=1.5162 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend34.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend35.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.pt/inherit2.C.diff?cvsroot=gcc&r1=1.7&r2=1.8
Fixed in the mainline.