Please see the attached sample file, functions g1() and g2() should produce the same output, but they do not. The difference is that g2() finds a template function when called with an unqualified name, g1() does not find the template function when called with a qualified name. GCC version: [zoltan@epcau-srv-dev:test]$ g++-4.5 -v Using built-in specs. Reading specs from /usr/lib64/gcc/x86_64-suse-linux/4.5/defaults.spec COLLECT_GCC=g++-4.5 COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.5/lto-wrapper Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,fortran --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.5 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.5 --enable-linux-futex --without-system-libunwind --enable-gold --with-plugin-ld=/usr/bin/gold --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux Thread model: posix gcc version 4.5.0 20100414 [gcc-4_5-branch revision 158342] (SUSE Linux)
Created attachment 25330 [details] bug
Comment on attachment 25330 [details] bug #include <iostream> namespace NS { template<class T> struct A { T t; }; template<class T> void f(T &t) { std::cout << "function 1" << std::endl; } template<class T> void g1(T &t) { // qualify with namespace NS::f(t); } template<class T> void g2(T &t) { // do not qualify with namespace f(t); } template<class T> void f(A<T> &t) { std::cout << "function 2" << std::endl; } } int main() { using namespace NS; A<int> a; g1(a); // this should print: "function 2", bug? g2(a); // this prints "function 2" correctly. return 0; }
NS::f(t); Binds at the point at definition because it is qualified. f(t); Does not bind and then does argument dependent lookup (ADL) at instantiation time.
(In reply to comment #3) > NS::f(t); > Binds at the point at definition because it is qualified. > f(t); > Does not bind and then does argument dependent lookup (ADL) at instantiation > time. Thanks. According to the C++ spec I have the lookup of names dependent on the template parameters is postponed until the actual template argument is known, and in this case NS::f() is dependent on a template argument, so I would think the lookup would be delayed till instantiation. Can you please point me to the paragraph in the standard that says qualified names bind at definition even if they depend on a template argument.
The name lookup is delayed until instantiation, however [temp.dep.candidate] says that the qualified lookup in g1 only finds declarations visible at the point of definition of g1: For a function call that depends on a template parameter, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2, 3.4.3) except that: — For the part of the lookup using unqualified name lookup (3.4.1) or qualified name lookup (3.4.3), only function declarations from the template definition context are found. — For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found.
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#448