These tricks may be obvious, but at least I’m going to write them down.
It is common to import an entire namespace into the global namespace. I’m not saying it’s a good idea, but it is common. The most notorious example is to put
using namespace std;
to import the std
namespace into the global namespace.
When working with the Windows Runtime, you often have rather deep namespaces. For example, we saw some time ago that we were operating in the Windows::
namespace. This is quite a mouthful, and it is common to put a
using namespace Windows::System::Profile::SystemManufacturers;
in your program just to save yourself the hassle of typing it all out.
However, things get complicated if you create name collisions.
For example, if you are using WRL, you will be working with the ABI::
namespace, but if you do a
using namespace ABI::Windows::System::Profile::SystemManufacturers;
you now have a problem because you have imported the name SmbiosÂInformation
twice:
using namespace Windows::System::Profile::SystemManufacturers; using namespace ABI::Windows::System::Profile::SystemManufacturers;
After these two declarations, the name SystemÂInformation
is now ambiguous. It could refer to Windows::
, via the first using
declaration, or it oculd refer to ABI::
SystemÂInformation
, via the second using
declaration.
I’ve worked around this by using namespace aliases:
namespace wspsm = Windows::System::Profile::SystemManufacturers; namespace awspsm = ABI::Windows::System::Profile::SystemManufacturers;
This lets me use wspsm::SmbiosÂInformation
and awspsm::SmbiosÂInformation
to refer to the C++/CX or ABI versions, respectively.
However, this gets clunky once you have multiple namespaces you want to access:
namespace wspsm = Windows::System::Profile::SystemManufacturers; namespace awspsm = ABI::Windows::System::Profile::SystemManufacturers; namespace wwspsm = winrt::Windows::System::Profile::SystemManufacturers; namespace wuvm = Windows::UI::ViewManagement; namespace awuvm = ABI::Windows::UI::ViewManagement; namespace wwuvm = winrt::Windows::UI::ViewManagement; namespace wsc = Windows::Security::Cryptography; namespace awsc = ABI::Windows::Security::Cryptography; namespace wwsc = winrt::Windows::Security::Cryptography;
because you have to juggle all these aliases. </`P>
But there’s a more attractive solution: Move names around by importing them into another namespace. (The name for this technique is “namespace composition”, covered in sections 14.4.3 and 14.4.4 of The C++ Programming Language.)
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; }
The first block of using
declarations imports the contents of the ABI::
, ABI::
, and ABI::
namespaces into the ABI
namespace.
Similarly for the other two blocks.
The upshot of this is that you can now do this
Old and busted | To get |
---|---|
New hotness | |
awspsm:: |
ABI:: SystemÂManufacturers::SmbiosInformation |
   ABI:: |
|
 wspsm:: |
Windows:: SystemÂManufacturers::SmbiosInformation |
    cx:: |
|
wwspsm:: |
winrt:: SystemÂManufacturers::SmbiosInformation |
 winrt:: |
|
 awuvm:: |
ABI:: ApplicationÂView |
   ABI:: |
|
  wuvm:: |
Windows:: ApplicationÂView |
    cx:: |
|
 wwuvm:: |
winrt:: ApplicationÂView |
 winrt:: |
|
  awsc:: |
ABI:: CryptographicÂBuffer |
   ABI:: |
|
   wsc:: |
Windows:: CryptographicÂBuffer |
    cx:: |
|
  wwsc:: |
winrt:: CryptographicÂBuffer |
 winrt:: |
In particular, this trick works with Windows Runtime classes because as a general rule, Windows Runtime type names are unique across all Windows Runtime namespaces, so you won’t inadvertently introduce a name collision by using
a bunch of Windows Runtime namespaces together.
The general rule makes Windows Runtime types easier to search for (both on the Web and in your code) because you will have fewer false positives.
Bonus chatter: The exception to the general rule is DirectX. Windows Runtime naming conventions permit the same name to be used in different versions of DirectX. This isn’t a problem because in practice, each application picks one version of DirectX and sticks with it; applications don’t try to mix-and-match different versions of DirectX.
Bonus bonus chatter: The above rule is on the books, but has yet to be exercised. As of this writing, the only version of DirectX in the Windows Runtime is DirectX11.
0 comments