Topic: template and type-dependent name resolution
Author: Michael Norrish <michael.norrish@nicta.com.au>
Date: Mon, 21 May 2007 23:26:20 CST Raw View
I'm confused by g++ 4.0.3's behaviour on the following program (and
its variants, indicated by comments):
----------------------------------------------------------------------
#include <iostream>
using namespace std;
namespace m0 {
namespace m {
class C { public: int x; };
}
}
namespace p {
template <class T> class Foo {
public:
T x;
int g() { return f(x); }
};
}
int h()
{
p::Foo<m0::m::C> foo;
return foo.g();
}
int main()
{
cout << h() << endl;
return 0;
}
namespace m0 {
// this works
namespace m {
int f (C &c) { cout << "Yay\n"; return 1; }
}
// but this does not
// int f(m::C &c) { cout << "Urk\n"; return 2; }
}
// this would also work (if m0::m::f isn't also around - if both are
// present, there is an ambiguous overloading error)
// int f(m0::m::C &c) { cout << "Cool\n"; return 3; }
----------------------------------------------------------------------
The first f (in m0::m) is found because it's in the same namespace as
the declaration of C.
The last f (commented out), is found by name resolution of the
template body, because it appears "in the namespace" of the template
definition. (Indeed, you can mask it by putting a declaration of f
into namespace p.) Of course, the last f is actually in the global
namespace, not in p, but p 'inherits' it.
The second f (commented out) is not found however, and this confuses
me. Why is the rule different for the namespaces associated with the
class argument as opposed to the template definition? I don't get any
inspiration from reading the language of 3.4.2 para 2, and 14.6.4.2)
Or is g++ just incorrect?
Thanks,
Michael.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Tue, 22 May 2007 22:44:37 GMT Raw View
Michael Norrish ha scritto:
>
> The first f (in m0::m) is found because it's in the same namespace as
> the declaration of C.
>
> The last f (commented out), is found by name resolution of the
> template body, because it appears "in the namespace" of the template
> definition. (Indeed, you can mask it by putting a declaration of f
> into namespace p.) Of course, the last f is actually in the global
> namespace, not in p, but p 'inherits' it.
>
> The second f (commented out) is not found however, and this confuses
> me. Why is the rule different for the namespaces associated with the
> class argument as opposed to the template definition? I don't get any
> inspiration from reading the language of 3.4.2 para 2, and 14.6.4.2)
>
> Or is g++ just incorrect?
>
I believe g++ is correct. 3.4.2/2 says:
"If T is a class type (including unions), its associated classes are:
the class itself; [...]. Its associated namespaces are the namespaces
in which its associated classes are defined."
m0::m::C is defined in m0::m. Even if m0::m is nested in m0, you can't
say that m0::m::C is defined in m0. (If you are not convinced about
that, consider that, in the scope of namespace m0, an unqualified name C
won't refer to m0::m::C.) So the list of associated namespaces contains
m0::m but not m0 and therefore m0 is not searched during ADL.
HTH,
Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]