overload resolution and namespaces

This is a discussion on overload resolution and namespaces within the c++ forums in Programming Languages category; In the following example, it seems that there should be an ambiguity in the call to ::foo(), but there isn't. Why? #include <stdio.h> namespace ns { void foo() { printf("namespace foo\n"); } } void foo() { printf("global foo\n"); } using namespace ns; int main() { ::foo(); } If the call to ::foo() is replaced by an unqualified foo(), the compilers (both gcc and Solaris CC) complain about ambiguity in resolving the overload between the global foo and the namespace foo. That's as expected. On the other hand, with the qualified call to ::foo(), name lookup (section 3.4.3/4) indicates that both ...

Go Back   Application Development Forum > Programming Languages > c++

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 09-06-2008, 05:29 PM
pr2345@gmail.com
Guest
 
Default overload resolution and namespaces

In the following example, it seems that there should be an ambiguity
in the call to ::foo(), but there isn't. Why?

#include <stdio.h>

namespace ns
{
void foo() { printf("namespace foo\n"); }
}

void foo() { printf("global foo\n"); }

using namespace ns;

int main()
{
::foo();
}

If the call to ::foo() is replaced by an unqualified foo(), the
compilers (both gcc and Solaris CC) complain about ambiguity in
resolving the overload between the global foo and the namespace foo.
That's as expected.

On the other hand, with the qualified call to ::foo(), name lookup
(section 3.4.3/4) indicates that both definitions of foo should be
found. (And to confirm that, if we comment out the global definition
of foo, ::foo resolves to ns::foo without any problem).

So it seems that there should be an overload set consisting of both
the global foo and the namespace foo.

I can't seem to find the section in the standard that covers how
overload resolution supposed to work in this case (as the signatures
of the two functions are identical). How is this supposed to work?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #2  
Old 09-07-2008, 07:20 AM
Sushrut Sardeshmukh
Guest
 
Default Re: overload resolution and namespaces

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
case 1: both foo () available and call using foo()
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
namespace ns
{
void foo() { printf("namespace foo\n"); }
}
void foo() { printf("global foo\n"); }
using namespace ns;
int main()
{
foo();
}

then compiler does complain because..

3.4.1.2
The declarations from the namespace nominated by a using-directive
become visible in a namespace
enclosing the using-directive;
so we have foo() // global and ns::foo() both available.
Hence compiler does not know which foo() you want to call.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
case 2 only one foo() available and call using ::foo()
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
namespace ns
{
void foo() { printf("namespace foo\n"); }
}
// void foo() { printf("global foo\n"); } // no more global foo()
using namespace ns;

int main()
{
::foo();
}

3.4.3.4
A name prefixed by the unary scope operator :: (5.1) is looked up in
global scope, in the translation unit
where it is used. The name shall be declared in global namespace scope
or shall be a name whose declaration
is visible in global scope because of a using-directive (3.4.3.2). The
use of :: allows a global name to
be referred to even if its identifier has been hidden (3.3.7).

read the part.... or shall be a name whose declaration is visible in
global scope because of a using-directive


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
case 3 both foo() available and call using ::foo()
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
namespace ns
{
void foo() { printf("namespace foo\n"); }
}
void foo() { printf("global foo\n"); }
using namespace ns;

int main()
{
::foo();
}

in 3.4.3.4
read the part.... The use of :: allows a global name to be referred to
even if its identifier has been hidden (3.3.7).


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #3  
Old 09-07-2008, 07:28 AM
Greg Herlihy
Guest
 
Default Re: overload resolution and namespaces

On Sep 6, 2:29 pm, pr2...@gmail.com wrote:
> In the following example, it seems that there should be an ambiguity
> in the call to ::foo(), but there isn't. Why?
>
> #include <stdio.h>
>
> namespace ns
> {
> void foo() { printf("namespace foo\n"); }
> }
>
> void foo() { printf("global foo\n"); }
>
> using namespace ns;
>
> int main()
> {
> ::foo();
> }


There is no ambiguity because - when resolving the qualified id
"::foo()", the "foo" declared in the global namespace ends up hiding
the foo (from the "ns" namespace) that was brought into the global
namespace via a using-directive:

"During the lookup of a name qualified by a namespace name,
declarations that would otherwise be made visible by a using-directive
can be hidden by declarations with the same name in the namespace
containing the using-directive." [§3.3.7/4].

Greg



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #4  
Old 09-08-2008, 09:39 AM
Alberto Ganesh Barbati
Guest
 
Default Re: overload resolution and namespaces

Greg Herlihy ha scritto:
> On Sep 6, 2:29 pm, pr2...@gmail.com wrote:
>> In the following example, it seems that there should be an ambiguity
>> in the call to ::foo(), but there isn't. Why?
>>
>> #include <stdio.h>
>>
>> namespace ns
>> {
>> void foo() { printf("namespace foo\n"); }
>> }
>>
>> void foo() { printf("global foo\n"); }
>>
>> using namespace ns;
>>
>> int main()
>> {
>> ::foo();
>> }

>
> There is no ambiguity because - when resolving the qualified id
> "::foo()", the "foo" declared in the global namespace ends up hiding
> the foo (from the "ns" namespace) that was brought into the global
> namespace via a using-directive:
>
> "During the lookup of a name qualified by a namespace name,
> declarations that would otherwise be made visible by a using-directive
> can be hidden by declarations with the same name in the namespace
> containing the using-directive." [§3.3.7/4].
>


That statement uses the verb "can", so it formally provides only a
possibility, not a guarantee. 3.4.3.2/2 provides a guarantee:

"Given X::m (where X is a user-declared namespace), or given ::m (where
is the global namespace), let S be the set of all declarations of m in
X and in the transitive closure of all namespaces nominated by
using-directives in X and its used namespaces, except that
using-directives are ignored in any namespace, including X, directly
containing one or more declarations of m. [...]"

(read in particular the last part of the sentence, from "except that..."
onwards).

HTH,

Ganesh


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 02:12 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.