A quick one for the gurus: C++11 allows unnamed namespaces to be declared inline
. This seems redundant to me; things declared in an unnamed namespace are already used as if they were declared in the enclosing namespace.
So my question is this: what does it mean to say
inline namespace /*anonymous*/ {
// stuff
}
and how is it different from the traditional
namespace /*anonymous*/ {
// stuff
}
that we know and love from C++98? Can anyone give an example of different behaviour when inline
is used?
EDIT: Just to clarify, since this question has been marked as a duplicate: I'm not asking about named inline namespaces in general. I understand the use-case there, and I think they're great. I'm specifically asking what it means to declare an unnamed namespace as inline
. Since unnamed namespaces are necessarily always local to a TU, the symbol versioning rational doesn't seem to apply, so I'm curious about what adding inline
actually does.
As an aside, the standard [7.3.1.1], regarding unnamed namespaces, says:
inline
appears if and only if it appears in the unnamed-namespace-definition
but this seems like a tautology to my non-language lawyer eyes -- "it appears in the definition iff it appears in the definition"! For bonus points, can anyone explain what this bit of standardese is actually saying?
EDIT: Cubbi claimed the bonus point in the comments:
the standard is saying that unnamed-namespace-definition behaves as if it were replaced by X where
inline
appears in X iff it appears in the unnamed-namespace-definition
Here is one use that I have found:
namespace widgets { inline namespace {
void foo();
} } // namespaces
void widgets::foo()
{
}
In this example, foo
has internal linkage and we can define the function later on by using the namespace::function
syntax to ensure that the function's signature is correct. If you were to not use the widgets
namespace then the void foo()
definition would define a totally different function. You also don't need to re-open the namespace saving you a level of indentation.
If there is another function called foo
in the widgets namespace
already then this will give you an ambiguity instead rather than a nasty ODR violation.