C++11 allows inline namespace
s, all members of which are also automatically in the enclosing namespace
. I cannot think of any useful application of this -- can somebody please give a brief, succinct example of a situation where an inline namespace
is needed and where it is the most idiomatic solution?
(Also, it is not clear to me what happens when a namespace
is declared inline
in one but not all declarations, which may live in different files. Isn't this begging for trouble?)
Inline namespaces are a library versioning feature akin to symbol versioning, but implemented purely at the C++11 level (ie. cross-platform) instead of being a feature of a specific binary executable format (ie. platform-specific).
It is a mechanism by which a library author can make a nested namespace look and act as if all its declarations were in the surrounding namespace (inline namespaces can be nested, so "more-nested" names percolate up all the way to the first non-inline namespace and look and act as if their declarations were in any of the namespaces in between, too).
As an example, consider the STL implementation of
vector
. If we had inline namespaces from the beginning of C++, then in C++98 the header<vector>
might have looked like this:Depending on the value of
__cplusplus
, either one or the othervector
implementation is chosen. If your codebase was written in pre-C++98 times, and you find that the C++98 version ofvector
is causing trouble for you when you upgrade your compiler, "all" you have to do is to find the references tostd::vector
in your codebase and replace them bystd::pre_cxx_1997::vector
.Come the next standard, and the STL vendor just repeats the procedure again, introducing a new namespace for
std::vector
withemplace_back
support (which requires C++11) and inlining that one iff__cplusplus == 201103L
.OK, so why do I need a new language feature for this? I can already do the following to have the same effect, no?
Depending on the value of
__cplusplus
, I get either one or the other of the implementations.And you'd be almost correct.
Consider the following valid C++98 user code (it was permitted to fully specialize templates that live in namespace
std
in C++98 already):This is perfectly valid code where the user supplies its own implementation of a vector for a set of type where she apparently knows a more efficient implementation than the one found in (her copy of) the STL.
But: When specializing a template, you need to do so in the namespace it was declared in. The Standard says that
vector
is declared in namespacestd
, so that's where the user rightfully expects to specialize the type.This code works with a non-versioned namespace
std
, or with the C++11 inline namespace feature, but not with the versioning trick that usedusing namespace <nested>
, because that exposes the implementation detail that the true namespace in whichvector
was defined was notstd
directly.There are other holes by which you could detect the nested namespace (see comments below), but inline namespaces plug them all. And that's all there is to it. Immensely useful for the future, but AFAIK the Standard doesn't prescribe inline namespace names for its own standard library (I'd love to be proven wrong on this, though), so it can only be used for third-party libraries, not the standard itself (unless the compiler vendors agree on a naming scheme).