'使用namespace foo;`没用?
假设我有一个将所有声明放在名称空间foo
。 我可以通过添加以下方法方便地使用该库:
using namespace foo;
到我的源文件。 但是,如果foo
任何无辜名称(例如class foo::socket
)现在与全局名称空间名称(例如::socket()
) ::socket()
。 更重要的是,没有办法消除它们的歧义! 看起来像using namespace
只对不与全局名称空间冲突的库有用,还是我缺少某些东西?
编辑:通过“消除歧义”我的意思是一次的范围,而不是在每个使用地点,这当然是可能的。
我想我们必须等待一个满意的解决方案。
回答你的问题 - 这不是无用的,它符合你的想法。 在某些情况下(如我在下面描述的那样,可以做一个可以接受的事情)
它确实可能使名称模糊不清,导入整个名称空间时必须非常小心,请参阅为什么“使用namespace std”被认为是不好的练习?
例如,我通常只将一个完整的名称空间导入一个像函数一样小的东西
void func() {
using namespace foo;
// ...
}
绝对不要在实现文件的顶部做它。 直到你确信它不会造成任何冲突。
更重要的是,没有办法消除它们的歧义!
你在这个问题上是错误的。 始终允许使用完全限定名称:
int main() {
using namespace foo;
foo::socket fs;
::socket s; // no ambiguity
}
你正确的是它确实可能很容易造成模糊。 因此,经验法则不是无条件地引用标识符。 如果您需要,请在最小范围内执行。 此外,试着拉你需要的东西。 即:
int main() {
using foo::reader; // not using namespace foo; for a single identifier.
reader r;
socket s; // no ambiguity;
}
当然,如果你需要命名空间中的很多东西,最好将所有东西都放到范围内,IMO。
作为一个侧面说明,有时将一个标识符拉入同一个范围内是一件好事。 考虑std::iter_swap
一个可能的实现:
template<class ForwardIt1, class ForwardIt2>
void iter_swap(ForwardIt1 a, ForwardIt2 b)
{
using std::swap;
swap(*a, *b);
}
您可能想知道为什么在这种情况下会使用using指令,但原因实际上是更好的代码。 如果迭代器指向名称空间foo中的用户定义的类,它定义了一个自定义非成员交换函数,那么该函数将在用参数相关查找找到后被调用。
另一方面,如果找不到自定义交换函数,则std::swap
将作为后备调用。 这是因为using指令使其成为重载解析期间候选函数集的一部分。
上一篇: Is `using namespace foo;` useless?
下一篇: Namespace questions: forward declaration and mixing namespaces