Language[lang]
C++ namespace: declare, nest, alias and reopen
- Section
- Language [lang]
- Standard
- C++17
- Compilers
- MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
- Published
- Length
- 6 min read
Abstract
A namespace in C++ is a named scope that keeps its names apart from the same names elsewhere: shop::total is the total declared inside namespace shop. A namespace can be reopened and split across files, nested (in one line since C++17, namespace app::net) and given a shorter alias. using shop::total; brings in one name; using namespace shop; adds none but lets every name in shop be found without the prefix; and an unnamed namespace keeps what is inside private to one source file.

A namespace in C++ is a named scope: a region of the program whose names do not collide with the same names elsewhere. namespace shop { int total = 0; } puts total inside shop, and code outside reaches it as shop::total. The standard library lives in a namespace called std, which is why you write std::cout.
A shop’s running total, as a whole program:
#include <iostream>
namespace shop {
int total = 0;
void add(int price) { total += price; }
}
int main() {
shop::add(5);
shop::add(3);
std::cout << "total: " << shop::total << '\n'; // total: 8
}— end example]
It printed total: 8. Inside shop, add uses total with no prefix; outside, main writes shop:: in front of both.
The samples are C++17, built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++), and all four behaved the same. Since When lists the first compiler releases for each standard’s features.
Why use namespaces in C++?
So that one name can mean two things in one program. An audio library and a video library may each have a function called play; in two namespaces both fit, and the name before :: says which one you call:
namespace audio {
void play() { std::cout << "audio: playing the track\n"; }
}
namespace video {
void play() { std::cout << "video: playing the clip\n"; }
}
int main() {
audio::play();
video::play();
}— end example]
It printed audio: playing the track, then video: playing the clip.

With no namespaces, the second play is a second definition of the same function:
void play() { std::cout << "audio: playing the track\n"; }
void play() { std::cout << "video: playing the clip\n"; } // error— end example]
GCC stopped at the second line with redefinition of 'void play()', and the other three rejected it too.
Can a namespace be reopened or split across files?
Yes. Every namespace shop { ... } block at the same level adds to the same namespace, and the blocks may sit in one file or in several ([basic.namespace]). That is how a header file and its source file share a namespace: the header declares the functions inside shop, and the source file defines them, either in another shop block or outside any block with the full name. This sample does both in one file:
namespace shop {
int total = 0;
int total_price(); // declared here, defined further down
}
namespace shop { // reopened: adds to the same namespace
void add(int price) { total += price; }
}
int shop::total_price() { // defined outside, with the full name
return total; // inside, total means shop::total
}— end example]
With a main that adds 5 and 3 and prints shop::total_price(), it printed total price: 8.
Using declaration vs using directive
A using declaration, using shop::total;, brings one name into the scope where you write it, so total alone means shop::total there. A using directive, using namespace shop;, makes every name in shop usable without the prefix. It adds no names to the scope it sits in; it changes where a name written without a prefix is looked up. With the shop of the first program:
void add_one() {
using namespace shop; // every name in shop, in this function
add(1); // shop::add
}
int main() {
using shop::total; // one name: total
shop::add(5);
add_one();
std::cout << "total: " << total << '\n'; // shop::total
}— end example]
It printed total: 6: 5 added in main, 1 in add_one.
A directive also lets you reach names you did not ask for, and two directives that offer the same function with the same parameters make a call with no prefix ambiguous:
int main() {
using namespace audio;
using namespace video;
play(); // error: audio::play or video::play?
}— end example]
GCC said call of overloaded 'play()' is ambiguous, and the other three rejected it too. using namespace std; is the same directive for the standard library: what using namespace std does, and what to write instead has its clashes, and argument-dependent lookup, the rule that lets a call find a function through its argument’s namespace.
How do you write a nested namespace?
Put one namespace inside another and reach its names through both, as app::net::send(). Since C++17 a single line opens both at once, namespace app::, and means the same as the two nested blocks:
namespace app {
namespace net {
void send() { std::cout << "net: sent\n"; }
}
}
namespace app::net { // C++17: opens both at once
void receive() { std::cout << "net: received\n"; }
}— end example]
Called as app::net::send() and app::net::receive(), it printed net: sent, then net: received. Built as C++14, MSVC refused the short form and asked for /std:c++17; Clang warned, and GCC warned only with -pedantic. Since When’s C++17 table has the first compiler releases that support it.
What is a namespace alias?
A namespace alias is a second, shorter name for a namespace: after namespace net = app::, net::send() calls app::net::send() (namespace aliases on cppreference). The alias you will meet most is fs, for std::filesystem (C++17, from <filesystem>):
namespace net = app::net; // a shorter name for app::net
namespace fs = std::filesystem;
int main() {
net::send();
std::cout << fs::path{"shop/cart.txt"}.filename().string() << '\n';
}— end example]
It printed net: sent, then cart.txt. An alias cannot be reopened: after it, namespace net { } failed on all four compilers, so add to the namespace under its real name, namespace app::.
What is an unnamed (anonymous) namespace?
An unnamed namespace, also called an anonymous namespace, is namespace { } with no name. What is inside can be used in this translation unit (the source file and the headers it includes) and nowhere else, because everything declared in it has internal linkage (Namespaces on cppreference). It is the C++ way to keep a helper function private to one file, where C code marks it static:
namespace { // no name: usable in this file only
int with_tax(int price) { return price + price / 5; }
}
int main() {
std::cout << "with tax: " << with_tax(10) << '\n';
}— end example]
It printed with tax: 12. with_tax needs no prefix because the block behaves as a namespace with a unique name followed by a using directive for it ([namespace.unnamed]).
The namespace forms at a glance
| You write | It does |
|---|---|
namespace shop { } |
declares shop, or reopens it to add names |
shop::total |
reaches total in shop from outside |
using shop::total; |
lets total alone mean shop::total in this scope |
using namespace shop; |
makes every name in shop usable without the prefix |
namespace app:: |
opens app and net inside it at once (C++17) |
namespace net = app:: |
gives app::net a shorter name |
namespace { } |
keeps what is inside to this source file |
The Language section has the other answers on the core language.
Questions
What is namespace std in C++?
It is the namespace the C++ standard library declares its names in, which is why you write std::cout, std::string and std::vector. Naming the namespace is not enough to use them: each std name comes from the standard header that declares it, so std::cout needs #include <iostream>.
What does :: mean in C++?
It is the scope resolution operator: the name on its right is looked up inside what is named on its left, so shop::total is the total declared in namespace shop. With nothing on its left, as in ::total, the name is looked up in the global namespace.
Can you declare a namespace inside a function or a class?
No. A namespace can be defined only at global scope or directly inside another namespace. All four compilers used here rejected one inside main, Clang with “namespaces can only be defined in global or namespace scope”, and all four rejected one inside a struct too.
What is the global namespace in C++?
It is where the names declared outside every namespace live. A leading ::, as in ::total, names the global one explicitly, even where a local variable of the same name hides it: with a global total of 100 and a local total of 5, the sample printed local: 5 for total and global: 100 for ::total.
What is an inline namespace in C++?
A namespace declared with inline namespace, available since C++11. Its members can be used in most respects as though they were members of the enclosing namespace, so code reaches them without naming the inner one. Libraries use it to keep versions of their names apart, as in inline namespace v2.
Should you write using namespace std?
Not at global scope in a header: every file that includes the header gets the directive, and its own names can then clash with those of std. Inside a function or in a source file it is allowed, at a price: a global name of yours can become ambiguous with a std name, and a call can silently run a std function instead of yours. Cpp Next’s article on using namespace std has the cases and what to write instead.
Sources
- Namespacescppreference.com
- Namespace aliasescppreference.com
- [basic.namespace] NamespacesC++ standard working draft
- [namespace.unnamed] Unnamed namespacesC++ standard working draft
- [basic.link] Program and linkageC++ standard working draft
- SF.21: Don’t use an unnamed (anonymous) namespace in a headerC++ Core Guidelines