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 namespace Windows::System::Profile::SystemManufacturers;
using namespace Windows::UI::ViewManagement;
using namespace Windows::Security::Cryptography;
}
namespace cx
{
using namespace Windows::System::Profile::SystemManufacturers;
using namespace Windows::UI::ViewManagement;
using namespace Windows::Security::Cryptography;
}
namespace winrt
{
using namespace Windows::System::Profile::SystemManufacturers;
using namespace Windows::UI::ViewManagement;
using namespace 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_somethingY::, and do_somethingZ::. 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.
0 comments