Stupid C++ namespace tricks

综合编程 2018-05-16 阅读原文

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

责编内容by:The Old New Thing阅读原文】。感谢您的支持!

您可能感兴趣的

为 untp 添加解密受保护 PVR 功能 前些日志, 有 G友 为 untp 添加了这么一条 issue : 还是比较有意思的, 早就知道 TexturePacker 提供了加密资源的功能, 但还没有实际使用过, 何不借此机会研究一下 ? 一. 初探 Cont...
win,windows 添加开机应用程序 步骤一: 创建文件setup.bat 添加以下代码 #CODE START@echo off echo **************START APPLIST**************** ping ...
CppCon 2017: ThinLTO: Scalable and Incremental Lin... Have you registered for CppCon 2018 in September? Early bird registration is open now . While we wait for thi...
windows多网卡上网冲突解决办法 PC装有多网卡的时候,经常会因为有多个网关导致网络罢工: 解决办法 多个网卡中只能有一个网卡设置网关,一般选择是需要上外网的网卡设置网关(也可以自动设定),其他的网卡只设置IP地址,子网掩码,DNS,网...
学习C#中的字符串string 洗脑价值观 by 杂学的程序员 人类有了文字,就可以记录下来历史了,而计算机有了字符串,黑客们的历史也就开始了. C#定义了一个基本的类 string , 专门用于对字符串的操作。 记住,它是引用类型. 这个...