namespace wraps a block of declarations under a named scope, accessed with the :: (scope resolution) operator — myLib::Vector and otherLib::Vector are two entirely distinct types with the same short name, disambiguated by their namespace prefix. A using declaration or using directive can bring a specific name, or an entire namespace's names, into the current scope without the prefix, but using namespace std; at global scope in a header file is widely discouraged, since it forces that pollution onto every file that includes the header, defeating much of namespaces' purpose.
Declaring and using a namespace
The :: operator disambiguates exactly which Vector is meant — without it, if both namespaces were in scope simultaneously, the name alone would be genuinely ambiguous.
namespace geometry {
class Vector {
public:
double x, y;
};
}
namespace physics {
class Vector { // a COMPLETELY DIFFERENT class, same short name — zero conflict
public:
double magnitude, direction;
};
}
geometry::Vector g{1.0, 2.0};
physics::Vector p{5.0, 90.0};using declarations vs using directives
A using DECLARATION brings in just one specific name, keeping most of the namespace's protection; a using DIRECTIVE brings in everything, which is exactly why it's discouraged in header files — it silently defeats namespacing for every file that includes that header.
using std::cout; // using DECLARATION — brings in just cout, nothing else
cout << "hello\n"; // no std:: prefix needed for cout specifically
using namespace std; // using DIRECTIVE — brings in EVERYTHING from std
// fine in a small .cpp file, discouraged in headersNested namespaces
Since C++17, nested namespaces can be written with a single :: chain instead of stacking separate namespace blocks — a small but genuinely useful readability improvement for deeply-nested library code.
// before C++17
namespace company {
namespace project {
namespace utils {
void helper();
}
}
}
// C++17+: the concise equivalent
namespace company::project::utils {
void helper();
}