我很容易养成了在标准标识符前面加上前缀std::
而不是在using namespace std;
. 但是,我已经开始接触 C#,并且我注意到添加任何必要的 using 指令是非常正常的,即,您会看到:
using System;
Console.Write("foo");
代替:
System.Console.Write("foo");
显然,正如我从关于这个主题的 C# 问题中发现的那样,这种用法来自于这样一个事实,即 C# 中的各个系统命名空间比 C++ 中的要小得多std
,因此消除了与名称冲突相关的问题,因为有很多可能性较小(如果库使用名称冲突进行更新,您可以将其替换为完全限定名称),并消除与出现大量 Intellisense 选项相关的问题,因为名称空间小到足以处理。
那么问题是,如果这些是在 C# 中使用 using 指令的长期理由,那么 C++ 是否也是如此?将其应用于较小的第三方命名空间以及您自己的较小命名空间通常可以接受吗?
现在我意识到这可能会引起一些争议,我想借此机会要求它不会变成争论。一个好的答案应该包括一个基础,即优点或缺点,以及如何使用一种方式而不是另一种方式真正产生有价值的差异。
我问这个的原因是为了澄清这个问题,并可能消除在 C++ 中使用指令必须是一件坏事的观念。当然,如果需要,可以使用命名空间别名来减少较长的命名空间名称,如果需要,仍然可以使用完全限定的名称,但有时使用指令可以极大地简化访问某些成员,例如用户定义的文字运算符,据我所知,没有 ADL 的形式,这意味着您要么必须使用 using 指令,要么通过函数语法调用运算符方法,这首先破坏了使用运算符的整个目的。
例如,我有一个命名空间(包括一个表示键盘键的结构,以及作为可读替代访问方式的文字后缀:
"caps lock"_key.disable();
这里的问题是,除非您之前插入了using namespace Whatever;
or using Whatever::operator"" _key;
,否则代码将无法编译,这对用户来说是个坏消息。
使用指令在涉及或在标头中以这样的方式使用时会出现明显的问题std
,它们会为该标头的用户带来不需要的额外内容,但是当包含在比包含标题?由于不必每次都键入每个限定符而节省的击键确实加起来了,并且借助当今的 Intellisense 功能,找出不合格标识符属于哪个命名空间就像将鼠标悬停在它上面一样容易。