Stupid C++ namespace tricks

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::
System::
Profile::
System­Manufacturers
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::
Windows::
System::
Profile::
System­Manufacturers
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::
System::
Profile::
System­Manufacturers::
System­Information
, via the first using
declaration,
or it oculd refer to ABI::
Windows::
System::
Profile::
System­Manufacturers::
System­Information
, via the second using
declaration.

I’ve worked around this by using namespace aliases:

using wspsm = Windows::System::Profile::SystemManufacturers;
using 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:

using wspsm = Windows::System::Profile::SystemManufacturers;
using awspsm = ABI::Windows::System::Profile::SystemManufacturers;
using wwspsm = winrt::Windows::System::Profile::SystemManufacturers;

using wuvm = Windows::UI::ViewManagement;
using awuvm = ABI::Windows::UI::ViewManagement;
using wwuvm = winrt::Windows::UI::ViewManagement;

using wsc = Windows::Security::Cryptography;
using awsc = ABI::Windows::Security::Cryptography;
using wwsc = winrt::Windows::Security::Cryptography;

because you have to juggle all these aliases.

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::
Windows::
System::
Profile::
System­Manufacturers
, ABI::
Windows::
UI::
View­Management
,
and ABI::
Windows::
Security::
Cryptography
namespaces
into the ABI
namespace.

Similarly for the other two blocks.

The upshot of this is that you can now do this

Old and bustedTo get
New hotness
awspsm::
Smbios­Information
ABI::
Windows::
System::
Profile::
System­Manufacturers::
SmbiosInformation
ABI::
Smbios­Information
wspsm::
Smbios­Information
Windows::
System::
Profile::
System­Manufacturers::
SmbiosInformation
cx::
Smbios­Information
wwspsm::
Smbios­Information
winrt::
Windows::
System::
Profile::
System­Manufacturers::
SmbiosInformation
winrt::
Smbios­Information
awuvm::
Application­View
ABI::
Windows::
UI::
View­Management::
Application­View
ABI::
Application­View
wuvm::
Application­View
Windows::
UI::
View­Management::
Application­View
cx::
Application­View
wwuvm::
Application­View
winrt::
Windows::
UI::
View­Management::
Application­View
winrt::
Application­View
awsc::
Cryptographic­Buffer
ABI::
Windows::
Security::
Cryptography::
Cryptographic­Buffer
ABI::
Cryptographic­Buffer
wsc::
Cryptographic­Buffer
Windows::
Security::
Cryptography::
Cryptographic­Buffer
cx::
Cryptographic­Buffer
wwsc::
Cryptographic­Buffer
winrt::
Windows::
Security::
Cryptography::
Cryptographic­Buffer
winrt::
Cryptographic­Buffer

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.

责编内容来自:The Old New Thing (源链) | 更多关于

阅读提示:酷辣虫无法对本内容的真实性提供任何保证,请自行验证并承担相关的风险与后果!
本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 综合编程 » Stupid C++ namespace tricks

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录