4

I'm trying to understand why this program does not give an name-lookup ambiguity for i:

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X;
    }

    using namespace P;

    int l = i;
}

int main() {}

If we modify it like this we get a name-lookup ambiguity:

namespace X { int i = 1; }

namespace P {        
    int i = 2;
    using namespace X;
}

using namespace P;

int l = i;

int main() {}

The only change I made here is to remove the namespace Q and place it's content in the global namespace instead.

I have tried with 3 different compilers:

The all give the results stated in this email, and i'm trying to find out why.

Can anyone explain the behaviour in terms of the c++ standard? I fail to understand it.

Supremum
  • 542
  • 7
  • 23
  • 2
    Hasn't this just been answered on std-discussion? https://groups.google.com/a/isocpp.org/d/msg/std-discussion/7K4p4FCdq6o/9bDtklvVzZgJ – dyp Jul 18 '15 at 11:40
  • 1
    On second thought, this is a valid question on SO, but probably a duplicate. – dyp Jul 18 '15 at 11:43
  • 2
    Related/duplicate: http://stackoverflow.com/q/10741428/ – dyp Jul 18 '15 at 11:45

1 Answers1

1

In the first program used variable i is defined in namespace P because the using directive

using namespace X;

places declarations of X in the global namespace (the common namepsace for X and P). Thus the declaration of i in P (more precisely in Q due to another using directive) hides the declaration of X::i in the global namespace.

From the C++ Standard (3.4.1 Unqualified name lookup)

2 The declarations from the namespace nominated by a using-directive become visible in a namespace enclosing the using-directive; see 7.3.4.

So we have for the first program

namespace X { int i = 1; }

namespace Q {    
    namespace P {        
        int i = 2;
        using namespace X; // 1
    }

    using namespace P; // 2

    int l = i;
}

that the enclosing namespace for using directive #1 is the global namespace and the enclosing namespace for using directive #2 is the namepsace Q.

In the second program the both definitions of i are placed in the global namespace due to these two using directives

//...
using namespace X;
//...
using namespace P;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335