23 c++ namespaces global
在C++中,我们应该在全局命名空间中添加东西::吗?
例如,使用WinAPI的,这是用C的时候,应该怎么做::HANDLE,而不是HANDLE和::LoadLibrary替代LoadLibrary?C++对此有何看法?这通常是一个好主意,考虑可读性和可维护性等问题?
Arm*_*yan 11
C++中的名称可以是合格且不合格的.限定和非限定名称查找有不同的规则.::HANDLE是一个合格的名称,而是HANDLE一个不合格的名称.请考虑以下示例:
#include <windows.h>
int main()
{
int HANDLE;
HANDLE x; //ERROR HANDLE IS NOT A TYPE
::HANDLE y; //OK, qualified name lookup finds the global HANDLE
}
Run Code Online (Sandbox Code Playgroud)
我认为选择HANDLEvs.的决定::HANDLE是编码风格的问题.当然,正如我的例子所示,可能存在必须符合资格的情况.所以,你不妨使用::以防万一,除非语法对你有些恶心.
由于C中不存在名称空间,请不要使用:: HANDLE来访问HANDLE类型.
使用prepending :: for全局命名空间是一个可读性的好主意,您知道要访问的类型来自全局命名空间.
此外,如果你在一个嵌套的命名空间并声明自己的HANDLE类型(例如),那么编译器将使用这个而不是windows.h!
因此,在嵌套命名空间中工作时,总是更喜欢使用:: before names.
主要的兴趣点是从编译器的角度来看差异是什么,正如已经说过的那样,如果你包括::那么你使用的是合格的查找,而不是不合格的查找.
使用限定查找的优点是它能够始终精确定位特定符号.缺点是它将始终精确定位该特定符号 - 它将禁用Argument Dependent Lookup.ADL是该语言的一个重要且有用的部分,通过限定你有效地禁用它,这很糟糕.
考虑到您f在全局命名空间中有一个函数,并且您T在命名空间中添加了一个类型N.不要认为你想要添加一个f带有Tas参数的重载.遵循接口原则,您可以添加f到N命名空间,就像f实际执行的操作一样T,它也属于该类型.在这种情况下,如果您的代码::f(obj)在未知类型U的对象上调用(考虑通用代码),则编译器将无法将其::N::f(obj)作为潜在的重载,因为代码明确要求全局命名空间中的重载.
使用非限定查找使您可以自由地定义它们所属的函数以及用作参数的类型.虽然它并不完全相同,但考虑使用swap,如果你有资格,std::swap那么它就不会void swap( T&, T& )在你的N命名空间内捡起你的手......
当编译器无法获取我想要的元素时,我只会完全限定标识符.