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