Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| c_namespaces [2018/02/01 10:32] – [Overview] rpjday | c_namespaces [2018/02/01 14:50] (current) – [using-Directives] rpjday | ||
|---|---|---|---|
| Line 41: | Line 41: | ||
| namespace ATT = American_Telephone_and_Telegraph; | namespace ATT = American_Telephone_and_Telegraph; | ||
| </ | </ | ||
| + | |||
| + | Also, namespace identifier is "... either a previously unused identifier, in which case this is // | ||
| ===== Extensibility (namespaces are " | ===== Extensibility (namespaces are " | ||
| 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-// | NOTE: "A using-// | ||
| Line 68: | Line 72: | ||
| ==== using-Declarations ==== | ==== using-Declarations ==== | ||
| + | |||
| + | Read [[http:// | ||
| "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: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | Useful for introducing base class members into derived class definitions. | ||
| ==== using-Directives ==== | ==== using-Directives ==== | ||
| + | |||
| + | cppreference.com link [[http:// | ||
| "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**: | **IMPORTANT**: | ||
| + | |||
| + | Can also rename for clarity: | ||
| + | |||
| + | < | ||
| + | namespace Lib2 { | ||
| + | using namespace His_lib; // everything from His_lib | ||
| + | using namespace Her_lib; // everything from Her_lib | ||
| + | |||
| + | using His_lib:: | ||
| + | using Her_lib:: | ||
| + | |||
| + | using Her_string = Her_lib:: | ||
| + | template< | ||
| + | using His_vec = His_lib:: | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| ===== Nested namespaces ===== | ===== Nested namespaces ===== | ||
| - | Coming soon ... | + | < |
| + | void h(); | ||
| + | |||
| + | namespace X { | ||
| + | void g(); | ||
| + | // ... | ||
| + | namespace Y { | ||
| + | void f(); | ||
| + | void ff(); | ||
| + | // ... | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void X:: | ||
| + | { | ||
| + | f(); g(); h(); // all fine | ||
| + | } | ||
| + | |||
| + | void X::g() | ||
| + | { | ||
| + | f(); // error: no f() in X | ||
| + | Y:: | ||
| + | } | ||
| + | |||
| + | void h() | ||
| + | { | ||
| + | f(); // error: no global f() | ||
| + | Y:: | ||
| + | X:: | ||
| + | X:: | ||
| + | } | ||
| + | </ | ||
| + | NOTE: C++17 allows '' | ||
| ===== Namespace aliases ===== | ===== Namespace aliases ===== | ||
| Line 149: | Line 217: | ||
| </ | </ | ||
| - | 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: | ||
| + | |||
| + | < | ||
| + | namespace Lib | ||
| + | inline namespace V2_0 { | ||
| + | ... V2.0 declarations ... | ||
| + | } | ||
| + | | ||
| + | namespace V1_0 { | ||
| + | ... V1.0 declarations ... | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Or create your own namespace based on that feature: | ||
| < | < | ||
| Line 190: | Line 272: | ||
| </ | </ | ||
| + | One last weird variation, where you can choose your own default: | ||
| + | |||
| + | < | ||
| + | namespace MyDefault { | ||
| + | inline | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | "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. |
| + | |||
| + | < | ||
| + | #include " | ||
| + | namespace { | ||
| + | int a; | ||
| + | void f() {...} | ||
| + | int g() | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | An unnamed namespace has an implied using-directive. | ||
| + | " | ||
| ===== Argument dependent lookup (ADL) ===== | ===== Argument dependent lookup (ADL) ===== | ||