A little while ago, I noted a technique formally known as namespace composition. There was one section that appeared to confuse some people:
namespace ABI { using Windows::System::Profile::SystemManufacturers; using Windows::UI::ViewManagement; using Windows::Security::Cryptography; } namespace cx { using Windows::System::Profile::SystemManufacturers; using Windows::UI::ViewManagement; using Windows::Security::Cryptography; } namespace winrt { using Windows::System::Profile::SystemManufacturers; using Windows::UI::ViewManagement; using Windows::Security::Cryptography; }
Was this a copy/paste error? After all, the same three namespaces are being imported each time.
Well, no, actually. The text is the same, but each one is interpreted differently.
Let's take a simpler example:
namespace X { namespace W { void f(); }} namespace Y { namespace W { void f(); }} namespace W { void f(); } namespace X { using namespace W; auto do_something = f; } namespace Y { using namespace W; auto do_something = f; } namespace Z { using namespace W; auto do_something = f; }
Each of the three namespaces contain a using namespace W;
,
but each one refers to a different namespace,
which you can see by pasting the above into
Compiler Explorer
and observing the definitions of
X::
,
do_something
Y::
,
and
do_something
Z::
.
do_something
The first using namespace W;
takes place inside a
namespace X
,
so the search begins relative to that namespace,
and we find it at ::X::W
.
Similarly, the second
using namespace W;
takes place inside a
namespace Y
,
so the search begins relative to that namespace,
and we find it at ::Y::W
.
The third using namespace W;
takes place inside a
namespace Z
,
so the search begins relative to that namespace.
There is no
::Z::W
,
so we resume our search at the next outer namespace,
which is the global namespace,
and we find it as ::W
.
Even though the three namespace imports are textually identical, they have different effects because they each occur in different contexts.
I wrote it this way because it showed that I was "pulling in" the relative namespace declarations into the corresponding first-level namespace.