Topic: Namespace composition and selection


Author: khadrin@hotmail.com (Stephen J. Smith)
Date: Sun, 14 Oct 2001 22:09:44 GMT
Raw View
Mike Ferrel <mike_ferrel@agilent.com> wrote in message news:<3BC1E3EC.590448E4@agilent.com>...

> int main()
> {
>    using namespace Mine;
>    A a;        // errors, complaints of ambiguity
> }

"A a;" should be "X a;".

> So, my questions are, can I compose and select this way?  Are the
> compilers wrong?

The compilers are correct (except Borland).

> Comeau and g++ are happy if I replace using namespace Mine with
> using Mine::X, but should I have to do that?

Also note that replacing "X a;" with "Mine::X a;" will resolve the
ambiguity.  Why?  The former is governed by unqualified name lookup
rules, while the latter is governed by qualified name lookup rules.

Unqualified name lookup is covered in 3.4.1 paragraph 2:

    The declarations from the namespace nominated by a using-directive
    become visible in a namespace enclosing the using-directive;
    see 7.3.4. For the purpose of the unqualified name lookup rules
    described in 3.4.1, the declarations from the namespace nominated
    by the using-directive are considered members of that enclosing
    namespace.

Therefore, since using-directives are transitive (see 7.3.4), when
you say "X a;" as above, all the names from your various using
directives are treated as if they are declared in an enclosing
namespace.  The enclosing namespace is the global namespace in this
case.  Therefore the use of X is ambiguous.

Qualified name lookup is covered in 3.4.3.2

    Given X::m (where X is a user declared namespace), or given ::m
    (where X 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.

Therefore, since "using A::X;" is apparently a 'direct declaration'--
I say apparently because I don't believe that term is ever
defined--names from the other using-directives are not considered.
There is no ambiguity.

> Is my understanding of namespaces and using directives and declarations
> flawed?

Perhaps, but this feature has some dark corners.

It would be nice if you could resolve the ambiguities in a wrapper
namespace with a set of using-declarations only once.  You can as
long as you avoid unqualified lookup of any ambiguous names.
For example, you are free to leave the "using namespace Mine;"
at block scope in main and use any unambiguous names from Mine
without qualification.  For potentially ambiguous names, such as
X in your example, you must either provide a using declaration
or use qualified names.

To test your understanding explain why this example is correct:

namespace A {
    int i;
}

namespace B {
    int i;
    int y;
}

namespace AB {
    using namespace A;
    using namespace B;

    using A::i;
}

int main()
{
    using AB::i;
    {{{{
        using namespace AB;

        y = 0;
        i = 0;  // ok: no ambiguity
    }}}}
}

Try moving the using-declaration "using AB::i;" to global scope.  Why
does that fail?

Stephen J. Smith

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Mike Ferrel <mike_ferrel@agilent.com>
Date: Tue, 9 Oct 2001 02:50:33 GMT
Raw View
Mike Ferrel wrote:
>
> I have recently been able to start using namespaces in my code, and have
> been reading Stroustrup, among others, to understand their use.
>
> In TCP3L, Stroustrup gives an example of composing a new namespace from
> existing ones, and resolving clashes and ambiguities.
>
> Simplified, it is:
>
> namespace A {
>    class X { };
>    // ...
> }
>
> namespace B {
>    class X { };
>    // ...
> }
>
> namespace Mine {
>    using namespace A;   // everything from A
>    using namespace B;   // everything from B
>
>    using A::X;   // resolve potential clash in favor of A
>
>    // ...
> }
>
> He gives no example of use, but most of my attempts fail
>
> int main()
> {
>    using namespace Mine;
>    A a;        // errors, complaints of ambiguity
     ^   arghhh!  I meant X
> }
>
> g++ 3.0 complains X is undeclared, Comeau online complains it is
> ambiguous,
> Borland 5.5 throws up its hands in the definition of Mine.
>
> Comeau and g++ are happy if I replace using namespace Mine with
> using Mine::X, but should I have to do that?
>
> So, my questions are, can I compose and select this way?  Are the
> compilers wrong?
> Is my understanding of namespaces and using directives and declarations
> flawed?
>
> Thanks for any help.
>
> Mike Ferrel
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Mike Ferrel <mike_ferrel@agilent.com>
Date: Mon, 8 Oct 2001 19:03:32 GMT
Raw View
I have recently been able to start using namespaces in my code, and have
been reading Stroustrup, among others, to understand their use.

In TCP3L, Stroustrup gives an example of composing a new namespace from
existing ones, and resolving clashes and ambiguities.

Simplified, it is:

namespace A {
   class X { };
   // ...
}

namespace B {
   class X { };
   // ...
}

namespace Mine {
   using namespace A;   // everything from A
   using namespace B;   // everything from B

   using A::X;   // resolve potential clash in favor of A

   // ...
}

He gives no example of use, but most of my attempts fail

int main()
{
   using namespace Mine;
   A a;        // errors, complaints of ambiguity
}

g++ 3.0 complains X is undeclared, Comeau online complains it is
ambiguous,
Borland 5.5 throws up its hands in the definition of Mine.

Comeau and g++ are happy if I replace using namespace Mine with
using Mine::X, but should I have to do that?

So, my questions are, can I compose and select this way?  Are the
compilers wrong?
Is my understanding of namespaces and using directives and declarations
flawed?

Thanks for any help.

Mike Ferrel

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]