Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
c_namespaces [2018/02/01 10:32] – [Overview] rpjdayc_namespaces [2018/02/01 14:50] (current) – [using-Directives] rpjday
Line 41: Line 41:
 namespace ATT = American_Telephone_and_Telegraph; // namespace alias namespace ATT = American_Telephone_and_Telegraph; // namespace alias
 </code> </code>
 +
 +Also, namespace identifier is "... either a previously unused identifier, in which case this is //original-namespace-definition// or the name of a namespace, in which case this is //extension-namespace-definition//."
  
 ===== Extensibility (namespaces are "open") ===== ===== Extensibility (namespaces are "open") =====
Line 61: Line 63:
   * A namespace alias cannot be used to re-open a namespace.   * A namespace alias cannot be used to re-open a namespace.
  
-===== using =====+===== using (declarations and definitions) ===== 
 + 
 +==== Distinction ====
  
 NOTE: "A using-//declaration// adds a name to a local scope (also, "introduces a synonym into a scope"). A using-//directive// does not; it simply renders names accessible in the scope in which they were declared." NOTE: "A using-//declaration// adds a name to a local scope (also, "introduces a synonym into a scope"). A using-//directive// does not; it simply renders names accessible in the scope in which they were declared."
Line 68: Line 72:
  
 ==== using-Declarations ==== ==== using-Declarations ====
 +
 +Read [[http://en.cppreference.com/w/cpp/language/namespace#Using-declarations|this]] carefully.
  
 "makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears." "makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same class scope, block scope, or namespace as where this using-declaration appears."
Line 89: Line 95:
 } }
 </code> </code>
 +
 +Useful for introducing base class members into derived class definitions.
  
 ==== using-Directives ==== ==== using-Directives ====
 +
 +cppreference.com link [[http://en.cppreference.com/w/cpp/language/namespace#Using-directives|here]].
  
 "From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name." "From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name."
Line 99: Line 109:
  
 Keep their use inside scopes (functions) to avoid massive side effects. Even worse, don't include them in global scopes in header files. Keep their use inside scopes (functions) to avoid massive side effects. Even worse, don't include them in global scopes in header files.
 +
 +==== Tradeoffs ====
 +
 +  * If some qualification is really common for several names, use a using-directive for that namespace.
 +  * If some qualification is common for a particular name from a namespace, use a using-de- claration for that name.
 +  * If a qualification for a name is uncommon, use explicit qualification to make it clear from where the name comes.
 +  * Don’t use explicit qualification for names in the same namespace as the user.
  
 ===== Composition and selection ===== ===== Composition and selection =====
Line 115: Line 132:
   // ...   // ...
 } }
 +
 +// Does the order of the following matter?
  
 namespace My_lib { namespace My_lib {
Line 126: Line 145:
  
 **IMPORTANT**: When looking into a namespace, names explicitly declared there (including names declared by using-declarations) take priority over names made accessible in another scope by a using-directive (see also §14.4.1). Consequently, a user of ''My_lib'' will see the name clashes for ''String'' and ''Vector'' resolved in favor of ''His_lib::String'' and ''Her_lib::Vector''. **IMPORTANT**: When looking into a namespace, names explicitly declared there (including names declared by using-declarations) take priority over names made accessible in another scope by a using-directive (see also §14.4.1). Consequently, a user of ''My_lib'' will see the name clashes for ''String'' and ''Vector'' resolved in favor of ''His_lib::String'' and ''Her_lib::Vector''.
 +
 +Can also rename for clarity:
 +
 +<code>
 +namespace Lib2 {
 +  using namespace His_lib; // everything from His_lib
 +  using namespace Her_lib; // everything from Her_lib
 +
 +  using His_lib::String; // resolve potential clash in favor of His_lib
 +  using Her_lib::Vector; // resolve potential clash in favor of Her_lib
 +
 +  using Her_string = Her_lib::String; // rename
 +  template<typename T>
 +    using His_vec = His_lib::Vector<T>; // rename
 +  ...
 +}
 +</code>
  
 ===== Nested namespaces ===== ===== Nested namespaces =====
  
-Coming soon ...+<code> 
 +void h(); 
 + 
 +namespace X { 
 +  void g(); 
 +  // ... 
 +  namespace Y { 
 +    void f(); 
 +    void ff(); 
 +    // ... 
 +  } 
 +
 + 
 +void X::Y::ff() 
 +
 +  f(); g(); h();   // all fine 
 +
 + 
 +void X::g() 
 +
 +  f();             // error: no f() in X 
 +  Y::f();          // OK 
 +
 + 
 +void h() 
 +
 +  f();             // error: no global f() 
 +  Y::f();          // error: no global Y 
 +  X::f();          // error: no f() in X 
 +  X::Y::f();       // OK 
 +
 +</code>
  
 +NOTE: C++17 allows ''namespace A::B::C { ... }''.
 ===== Namespace aliases ===== ===== Namespace aliases =====
  
Line 149: Line 217:
 </code> </code>
  
-A namespace alias cannot be used to re-open a namespace.+  * Aliases can be used to refer to nested namespaces. 
 +  * A namespace alias cannot be used to re-open a namespace.
  
-(Add ability to alias nested namespaces.) 
 ===== Inline namespaces (new in C++11) ===== ===== Inline namespaces (new in C++11) =====
  
Line 157: Line 225:
  
 Supports versioning: Supports versioning:
 +
 +<code>
 +namespace Lib
 +  inline namespace V2_0 {
 +    ... V2.0 declarations ...
 +  }
 +  
 +  namespace V1_0 {
 +    ... V1.0 declarations ...
 +  }
 +}
 +</code>
 +
 +Or create your own namespace based on that feature:
  
 <code> <code>
Line 190: Line 272:
 </code> </code>
  
 +One last weird variation, where you can choose your own default:
 +
 +<code>
 +namespace MyDefault {
 +  inline
 +  #include "V3_0.h"      // the new default
 +  #include "V3_2.h"
 +  #include "V2_4_2.h"
 +}
 +</code>
 +
 +"I do not recommend such intricate use of header files unless it is really necessary. The example above repeatedly violates the rules against including into a nonlocal scope and against having a syntactic construct span file boundaries (the use of inline); see §15.2.2. Sadly, I have seen worse."
 ===== Unnamed namespaces ===== ===== Unnamed namespaces =====
  
-Its members have potential scope from their point of declaration to the end of the translation unit, and have internal linkage.+Its members have potential scope from their point of declaration to the end of the translation unit, and have //internal// linkage. The aim is to preserve locality of code rather than to present an interface to users. 
 + 
 +<code> 
 +#include "header.h" 
 +namespace { 
 +  int a; 
 +  void f()  {...} 
 +  int g()   {...} 
 +
 +</code> 
 + 
 +An unnamed namespace has an implied using-directive.
  
 +"Unnamed namespaces in different translation units are different. As desired, there is no way of naming a member of an unnamed namespace from another translation unit."
 ===== Argument dependent lookup (ADL) ===== ===== Argument dependent lookup (ADL) =====
  
  • c_namespaces.1517481165.txt.gz
  • Last modified: 2018/02/01 10:32
  • by rpjday