<p>There's already a <a href="https://stackoverflow.com/questions/65365681/why-does-cs-using-namespace-work-the-way-it-does">question</a> on StackOverflow regarding this, but I feel like this platform is more appropriate for the question.</p>
<p>Why is it that when a using-directive is used inside a scope in C++, from the point of view of unqualified lookups in that scope, it's as if the names from the concerned namespaces are a part of the closest enclosing scope that contains both the using directive and the nominated namespace? Why isn't it something more straightforward like...the names are treated as part of the very scope in which the using directive has been used, or the names are treated as part of the global scope?</p>
<p>What could the thought-process behind this decision have been? Are there any notable benefits to it over the alternatives?</p>
<p>For example:</p>
<pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;

namespace x {
    namespace y {
        int i = 10;
    }
}

int i = 20;

int main() {
    using namespace x::y;
    std::cout &lt;&lt; i;            // ambiguous reference
}
</code></pre>
<p>Currently, this code doesn't compile as unqualified lookup for <code>i</code> inside <code>main</code> is an ambiguous reference, with the candidates being <code>::i</code> and <code>x::y::i</code>. This is because <code>using namespace x::y</code> comes into effect when the unqualified lookup goes up to the global scope, as that is the closest enclosing scope to main, such that both the nominated namespace (<code>x::y</code>) and the using directive are a part of the scope. And, then, there are two possible <code>i</code>'s that we could be referring to, hence the ambiguous reference.</p>
<p>If alternatively, what a using directive did was treat the names from the nominated namespace as being part of the current scope, this would not be an ambiguous reference and the code would compile and print <code>10</code> to the standard output. Unqualified lookup for <code>i</code>, in that case, would not even resolve up to the global scope.</p>
<p>As another example, consider this slightly modified code:</p>
<pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;

namespace x {
    namespace y {
        int i = 10;
    }
}

int i = 20;

int main() {
    using namespace x::y;
    int i = 30;
    std::cout &lt;&lt; i;            // this is fine
}
</code></pre>
<p>This code does compile, and prints <code>30</code> to the standard output. This is because the unqualified lookup for <code>i</code> comes to an end right inside <code>main</code>'s scope, and the lookup never resolves to the global scope, and the using directive never comes into effect.</p>
<p>In the alternate scenario where names from <code>x::y</code> are directly injected inside the concerned scope, this would be an ambiguous reference, as there would be two possible candidates for <code>i</code>, namely <code>main</code>'s <code>i = 30</code> and <code>x::y</code>'s <code>i = 10</code>.</p>
<p>If it helps clarify it even further, the alternative that I'm talking about in these examples is somewhat similar to using <code>from namespace_name import *</code> inside a scope in Python.</p>

<language-design><c++><namespaces>
Why do using-directives in C++ work the way they do?
CC BY-SA 4.0
2024-07-11T23:02:23.363Z
I intuit this is to support [argument-dependent lookup (ADL)](https://en.cppreference.com/w/cpp/language/adl) but I don’t know the details
Jon Purdy
CC BY-SA 4.0
2024-07-12T21:50:31.433Z
I think you've answered your own question with your first example -- `i` in that case SHOULD be ambiguous, in order to avoid surprising people when new symbols are added to a namespace.  Having *all* the symbols in a namespace just imported blindly into the current namespace would make using directives too dangerous to be useful.  Indeed, some coding standards already suggest disallowing using directives altogether, as they make figuring out what a name refers to too hard for casual readers of the code.
Chris Dodd
CC BY-SA 4.0
2024-07-14T09:53:50.287Z
@ChrisDodd What about having every name from the namespaces injected into the global namespace, though? That sounds much simpler, and the examples in the question will behave exactly the same way as they do now.
Rajdeep Sindhu
CC BY-SA 4.0
2024-07-15T00:20:18.690Z
@RajdeepSindhu: That would make it impossible to import a namespace with a symbol that conflicts with the global namespace (or another imported namespace), which would make it pretty much useless.  It also doesn't remove the issue of a new symbol added to a namespace suddenly completely changing the behavior of code that imports the namespace but otherwise does not use the new symbol.
Chris Dodd
# Why do using-directives in C++ work the way they do?
Posted by: username_0 on 2024-07-11
There's already a question on StackOverflow regarding this, but I feel like this platform is more appropriate for the question.
Why is it that when a using-directive is used inside a scope in C++, from the point of view of unqualified lookups in that scope, it's as if the names from the concerned namespaces are a part of the closest enclosing scope that contains both the using directive and the nominated namespace? Why isn't it something more straightforward like...the names are treated as part of the very scope in which the using directive has been used, or the names are treated as part of the global scope?
What could the thought-process behind this decision have been? Are there any notable benefits to it over the alternatives?
For example:
#include 

namespace x {
    namespace y {
        int i = 10;
    }
}

int i = 20;

int main() {
    using namespace x::y;
    std::cout << i;            // ambiguous reference
}

Currently, this code doesn't compile as unqualified lookup for i inside main is an ambiguous reference, with the candidates being ::i and x::y::i. This is because using namespace x::y comes into effect when the unqualified lookup goes up to the global scope, as that is the closest enclosing scope to main, such that both the nominated namespace (x::y) and the using directive are a part of the scope. And, then, there are two possible i's that we could be referring to, hence the ambiguous reference.
If alternatively, what a using directive did was treat the names from the nominated namespace as being part of the current scope, this would not be an ambiguous reference and the code would compile and print 10 to the standard output. Unqualified lookup for i, in that case, would not even resolve up to the global scope.
As another example, consider this slightly modified code:
#include 

namespace x {
    namespace y {
        int i = 10;
    }
}

int i = 20;

int main() {
    using namespace x::y;
    int i = 30;
    std::cout << i;            // this is fine
}

This code does compile, and prints 30 to the standard output. This is because the unqualified lookup for i comes to an end right inside main's scope, and the lookup never resolves to the global scope, and the using directive never comes into effect.
In the alternate scenario where names from x::y are directly injected inside the concerned scope, this would be an ambiguous reference, as there would be two possible candidates for i, namely main's i = 30 and x::y's i = 10.
If it helps clarify it even further, the alternative that I'm talking about in these examples is somewhat similar to using from namespace_name import * inside a scope in Python.
**Tags:** language-design c++ namespaces
> **Comments:**
> **username_1**: I intuit this is to support [argument-dependent lookup (ADL)](https://en.cppreference.com/w/cpp/language/adl) but I don’t know the details  
> **username_2**: I think you've answered your own question with your first example -- `i` in that case SHOULD be ambiguous, in order to avoid surprising people when new symbols are added to a namespace.  Having *all* the symbols in a namespace just imported blindly into the current namespace would make using directives too dangerous to be useful.  Indeed, some coding standards already suggest disallowing using directives altogether, as they make figuring out what a name refers to too hard for casual readers of the code.  
> **username_0**: @ChrisDodd What about having every name from the namespaces injected into the global namespace, though? That sounds much simpler, and the examples in the question will behave exactly the same way as they do now.  
> **username_2**: @RajdeepSindhu: That would make it impossible to import a namespace with a symbol that conflicts with the global namespace (or another imported namespace), which would make it pretty much useless.  It also doesn't remove the issue of a new symbol added to a namespace suddenly completely changing the behavior of code that imports the namespace but otherwise does not use the new symbol.  
---
## 0 answers
