Compiling the following program: template <typename VType> class Vector2 { private: VType c_[2]; public: typedef Vector2<VType> Self; Vector2(const VType x, const VType y) { c_[0] = x; c_[1] = y; } friend inline Self Max(const Self &v1, const Self &v2) { return Self(v1.c_[0], v1.c_[1]); } }; template <class T> Vector2<float> foo(T x) { Vector2<float> y(0,0); return Max(y, y); } int main() { foo(3); return 0; } gives the following error: test.cc: In function 'Vector2<float> foo(T) [with T = int]': test.cc:25: instantiated from here test.cc:13: error: no matching function for call to 'Max(Vector2<float>&, Vector2<float>&)' When compiled using GCC 4.4.0 trunk. The command line used for the compile is: g++ -c test.cc The output of gcc -v is: Using built-in specs. Target: i686-unknown-linux-gnu Configured with: src/configure --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-c99 --enable-long-long --with-gnu-as --with-gnu-ld --build=i686-host_pc-linux-gnu --host=i686-host_pc-linux-gnu --enable-shared=libgcc,libmudflap,libssp,libstdc++ --enable-languages=c,c++,fortran --with-gmp=/usr/grte/v1 --prefix=/tmp/gcc-4.3.1-glibc-2.3.6-grte/i686-unknown-linux-gnu --target=i686-unknown-linux-gnu --enable-static-nss --with-arch=pentium3 --with-tune=pentium4 Thread model: posix gcc version 4.4.0 20090114 (experimental) COLLECT_GCC_OPTIONS='-v' '-c' '-shared-libgcc' '-mtune=pentium4' '-march=pentium3'
Created attachment 17103 [details] Test case program
I think this code is invalid as the call to Max is not going to be dependent as the arguments are not dependent and can be looked up at the time the function is defined.
(In reply to comment #2) > I think this code is invalid as the call to Max is not going to be dependent as > the arguments are not dependent and can be looked up at the time the function > is defined. > I don't think I follow. While the arguments to Max are not dependent, other code inside of foo could be dependent on T (in the example, no such code exists). Shouldn't the fact that the function can be looked up at definition time make this code legal?
From a first look Max should be found during argument-dependent name-lookup. EDG confirms this theory. gcc 4.1 accepts this code.
Oh yes it only fails inside a template context.
Related to PR 34870 and 37804. friend and templates never got along.
4.2 and 4.3 handle this fine, I don't know why it was marked as a 4.2/4.3 regression.
Subject: Bug 38850 Author: jason Date: Fri Jan 16 05:04:26 2009 New Revision: 143422 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143422 Log: PR c++/38850 * pt.c (tsubst_copy_and_build): Tell finish_call_expr to accept hidden friends. Added: trunk/gcc/testsuite/g++.dg/template/koenig6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 38850 Author: jason Date: Fri Jan 16 06:08:09 2009 New Revision: 143423 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143423 Log: PR c++/38850 * pt.c (tsubst_copy_and_build): Tell finish_call_expr to accept hidden friends. Added: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/template/koenig6.C - copied unchanged from r143422, trunk/gcc/testsuite/g++.dg/template/koenig6.C Modified: branches/gcc-4_2-branch/gcc/cp/ChangeLog branches/gcc-4_2-branch/gcc/cp/pt.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Subject: Bug 38850 Author: jason Date: Fri Jan 16 06:08:20 2009 New Revision: 143424 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143424 Log: PR c++/38850 * pt.c (tsubst_copy_and_build): Tell finish_call_expr to accept hidden friends. Added: branches/gcc-4_3-branch/gcc/testsuite/g++.dg/template/koenig6.C - copied unchanged from r143422, trunk/gcc/testsuite/g++.dg/template/koenig6.C Modified: branches/gcc-4_3-branch/gcc/cp/ChangeLog branches/gcc-4_3-branch/gcc/cp/pt.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
Fixed.