Search code examples
c++language-lawyerusing-directivesname-lookup

How to interpret the rule [namespace.udir]p2 in the c++ standard?


I'm a bit confused about the implications of [namespace.udir]p2. Consider the following program:

namespace X { int i = 1; }

namespace Y { using namespace X; }

int main() { i = 2; }

In it name-lookup for i in main fails (i tried with GCC, Clang and visual c++). This does not seem to agree with [namespace.udir]p2 (http://eel.is/c++draft/dcl.dcl#namespace.udir-2):

A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup ([basic.lookup.unqual]), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]

With my program I'm applying this rule for the name i, declared by int i = 1; in X, the following way:

  • The using-directive: using namespace X;

  • The nominated namespace: X

  • The nearest enclosing namespace: The global namespace

Doesn't this imply that the unqualified name-lookup of i in main should find X::i? Why do I not get this result with any of the three compilers that I tried?


Solution

  • Using-directives make names visible in the scope in which they appear. For example, [basic.scope.namespace]p1

    for each using-directive that nominates the member’s namespace, the member’s potential scope includes that portion of the potential scope of the using-directive that follows the member’s point of declaration

    where the scope of a name is a part of the program where that name (the declaration of that name) can be found via unqualified lookup.

    Similarly, in [namespace.udir]p2,

    A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive.

    which basically says the same thing as the above quote.

    In the OP, the using-directive appears in namespace-scope of namespace Y; main is outside that scope, hence the using-directive has no effect on name lookup performed inside main.