From boris at kolpackov.net Mon Feb 23 16:28:37 2004 From: boris at kolpackov.net (Boris Kolpackov) Date: Mon Feb 23 16:26:12 2004 Subject: c++: notes on namespace Message-ID: <20040223222837.GA17775@kolpackov.net> Good day, Below are some notes on namespace usage in c++. DEC++ - The Design and Evolution of C++ PLC++ - The C++ Programming Language (special edition) TC++ - C++ Templates @@ A namespace should: - contain logically related set of features; the relation is usually suggested by the name of the namespace - be convenient and natural to use by not imposing significant notational burden @@ Two roles of namespaces: - avoid name clashes - group logically related entities @@ There are four mechanisms that allow you to access a name in a namespace: - membership - qualification - using-declaration - using-directive @@ Qualify names that are used once-twice; using-declare names that are used regularly. @@ Prefer using-declaration/using-directive in a function scope to using-declaration/using-directive in an outer scope. @@ Using-directive is an efficient way to 'inherit' namespaces. @@ Using-directive allow you to 'override' some declarations (see also DEC++ 17.4.3 last paragraph; PLC++ 8.2.8.2). @@ Using-declaration brings on all functions associated with the name. Thus it makes sense not to name unrelated functions with the same name. Also consider argument-dependent lookup (PLC++ 8.2.6; TC++ 9.2.1). @@ Namespace models: 'flat' (like std::) and 'tree' (with nested namespaces). @@ A 'tree' model can potentially be transformed into a 'flat' model via using-directives. @@ In the 'tree' model the outer namespace is usually for name- clash avoidance; the inner namespaces are for the concept grouping. @@ What names are good/bad for namespaces? What should namespace name signify? Bad: name of interface (parser, lexer, reader, etc). You will most likely want to name one of the entities in the namespace with this name. As a result you will end up with something ugly like 'parser::parser'. Namespace name should not correspond to a single entity but rather to a category to which names in the namespace logically belong. This makes the job of choosing the right name even trickier: you have to decide based on which principal to group. Should we use plural names? @@ In DEC++ 17.4 there is a suggestion that using-directive syntax is redundant and instead of writing 'using namespace A;' we could simple write 'using A;'. Note, however, that in the standard C++ 'using A;' and 'using namespace A;' have distinct semantics. @@ DEC 17.5.1 suggests an analogy between class inheritance and namespace nesting. This analogy doesn't scale to multiple inheritance, however (because a namespace cannot be nested into more than one namespace). A better analogy, IMO, would be using-directive in which case we get surprisingly precise matching. Consider the following example: struct A { void f (); }; struct B : A { void f (); }; struct C : A { void f (); // hides A::f }; struct D : A, B { // f is ambiguous using B::f; // choose B::f over A::f }; By replacing 'struct' with 'namespace' and inheritance with using-directive we get the same 'inheritance' semantic we have for classes: namespace A { void f (); }; namespace B { void f (); }; namespace C { using namespace A; void f (); // hides A::f }; struct D : A, B { using namespace A; using namespace B; // f is ambiguous using B::f; // choose B::f over A::f }; -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 652 bytes Desc: Digital signature Url : http://www.kolpackov.net/pipermail/notes/attachments/20040223/351d4097/attachment.bin