inline namespace
includes the content of the inlined namespace in the enclosing namespace, so
namespace Outer
{
inline namespace Inner
{
void foo();
}
}
is mostly equivalent to
namespace Outer
{
namespace Inner
{
void foo();
}
using Inner::foo;
}
but element from Outer::Inner::
and those associated into Outer::
are identical.
So following is equivalent
Outer::foo();
Outer::Inner::foo();
The alternative using namespace Inner;
would not be equivalent for some tricky parts as template specialization:
For
#include <outer.h> // See below
class MyCustomType;
namespace Outer
{
template <>
void foo<MyCustomType>() { std::cout << "Specialization"; }
}
The inline namespace allows the specialization of Outer::foo
// outer.h
// include guard omitted for simplification
namespace Outer
{
inline namespace Inner
{
template <typename T>
void foo() { std::cout << "Generic"; }
}
}
Whereas the using namespace
doesn't allow the specialization of Outer::foo
// outer.h
// include guard omitted for simplification
namespace Outer
{
namespace Inner
{
template <typename T>
void foo() { std::cout << "Generic"; }
}
using namespace Inner;
// Specialization of `Outer::foo` is not possible
// it should be `Outer::Inner::foo`.
}
Inline namespace is a way to allow several version to cohabit and defaulting to the inline
one
namespace MyNamespace
{
// Inline the last version
inline namespace Version2
{
void foo(); // New version
void bar();
}
namespace Version1 // The old one
{
void foo();
}
}
And with usage
MyNamespace::Version1::foo(); // old version
MyNamespace::Version2::foo(); // new version
MyNamespace::foo(); // default version : MyNamespace::Version1::foo();