Bug 50471 - Qualified lookup fails to find template function
Summary: Qualified lookup fails to find template function
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-21 05:41 UTC by Zoltan Glozik
Modified: 2011-09-21 10:22 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
bug (148 bytes, text/plain)
2011-09-21 05:41 UTC, Zoltan Glozik
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zoltan Glozik 2011-09-21 05:41:21 UTC
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)
Comment 1 Zoltan Glozik 2011-09-21 05:41:57 UTC
Created attachment 25330 [details]
bug
Comment 2 Zoltan Glozik 2011-09-21 05:43:44 UTC
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;
}
Comment 3 Andrew Pinski 2011-09-21 06:18:32 UTC
    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.
Comment 4 Zoltan Glozik 2011-09-21 06:43:29 UTC
(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.
Comment 5 Jonathan Wakely 2011-09-21 10:19:21 UTC
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.