Namespaces
Overview
C++'s namespace mechanism can be used to resolve name conflicts in complex projects.
For example: All contents of the C++ standard library are defined within the std namespace. If you define a variable named cin, you can access your defined cin variable via cin, and access the standard library's cin object via std::cin, without worrying about conflicts.
Declaration
The following code declares a namespace named A:
1 2 3 4 5 | |
After declaration, outside this namespace, you can access the f function inside namespace A via A::f(x), and access the cnt variable inside namespace A via A::cnt.
Namespace declarations can be nested, so the following code is also allowed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
The using Directive
After declaring a namespace, if you want to access members inside the namespace from outside, you need to prefix the member name with namespace::.
Is there a convenient way to directly access members inside a namespace using just the member name? The answer is yes. We can use the using directive.
The using directive has the following two forms:
using namespace::member;: This directive allows us to omit the namespace before a specific member name and access the member directly via the member name, effectively importing this member into the current scope.using namespace namespace;: This directive allows direct access to any member within the namespace using just the member name, effectively importing all members of this namespace into the current scope.
Therefore, if using namespace std; is executed, all names from std are introduced into the global namespace within the current scope. This allows us to use cin instead of std::cin and cout instead of std::cout.
The using directive may cause name conflicts!
Since using namespace std; introduces all names from std, if you declare a variable or function with the same name as one in std, it may cause a compilation error due to a name conflict.
Therefore, in engineering projects, using the using namespace namespace; directive is not recommended.
With the using directive, the code from C++ Syntax Basics can be written equivalently in these two ways:
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 | |
Unnamed Namespace
When we define a namespace within a scope solely to prevent name conflicts, its definition and usage can become very concise. We can use an unnamed namespace.
A namespace defined like namespace { /* something ... */ } (omitting the namespace name) is called an unnamed namespace. An unnamed namespace within a file is considered to have a unique name, different from all other namespaces, but multiple unnamed namespaces within the same scope are considered the same namespace. After an unnamed namespace is defined, the names within it can be found for use in the outer scope, as if a using namespace directive was added after the unnamed namespace definition.
Applications
Preventing Name Conflicts Between Subtasks
In problems with multiple subtasks, we can define a namespace for each subtask, declaring the variables and functions needed to solve that subtask within it. This way, even if two subtask implementations declare the same name, they won't conflict, making the subtasks independent of each other. This can facilitate debugging to some extent and improve program readability.
Preventing Conflicts with Standard Library and Environment-Introduced Names
Using namespaces can also prevent conflicts between names commonly used in competitive programming and standard names, as shown in the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
References
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用