Mitsuru Kariya
Mitsuru Kariya

Reputation: 948

Behavior of using-directive

I am confused about using-directive.

According to C++11 standard §7.3.4 p.3,

A using-directive does not add any members to the declarative region in which it appears.

Additionally, C++11 standard §7.3.4 does not deal with qualified name lookup.

Therefore, IMHO using-directive has no effect to qualified name lookup.
For example, I think that the following sample code should cause a compilation error.

#include <iostream>

namespace A {
    namespace B {
        int i = 1;
    }
    using namespace B;
}

int main()
{
    std::cout << A::i << std::endl;
}

But both gcc and clang compile this code successfully. (http://melpon.org/wandbox/permlink/rXPjE5k12yMtlvMg)

Furthermore, C++11 standard §7.3.1.1 says that an unnamed-namespace-definition behaves as if it were replaced by

inlineopt namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }

and shows following example (the unnecessary part were omitted).

namespace { int i; }    // unique::i

namespace A {
    namespace {
        int i;          // A::unique::i
    }
}

using namespace A;
void h() {
    i++;                // error: unique::i or A::unique::i
    A::i++;             // A::unique::i
}

This example says that A::i of function h can refer to the unnamed namespace member i.

Help me, I cannot understand any longer.

Would you teach me the right interpretation of using-directive?

Upvotes: 8

Views: 194

Answers (1)

user2249683
user2249683

Reputation:

Having 7.3.4

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 (3.4.1), 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 ]

A using-directive does not add any members to the declarative region in which it appears.

Interpreting above it says a using-directive is pulling the names into a scope, but not the declaration (namespace member), itself.

This might illustrate it:

namespace N {
    template <typename T> void f() {};
}

using namespace N;

// error: specialization of ‘template<class T> void N::f()’ in different
//        namespace
template <> void f<int>() {};

In the second example there are two unnamed namespaces:

Applying some little changes:

#include <iostream>

namespace { int i = 0; }    // unique::i

namespace A {
    namespace {
        int i = 1;          // A::unique::i
    }
}

using namespace A;

int main () {
    // i++; // error: unique::i or A::unique::i
    // The i having the value 1:
    std::cout << A::i << std::endl; // A::unique::i
    return 0;
}

Upvotes: 2

Related Questions