所以我必须使用Boost库的一些成员和std命名空间中的一些成员。现在,我已using boost::asio::ip::tcp;
已宣布,并且正在呼叫std::
的合适成员,例如tcp::iostream server()
。我有什么理由不添加其他using
,即using namespace std;
,然后调用所有std
内容而不添加std::
前缀?这两者可能会发生碰撞或导致故障吗?
答案 0 :(得分:3)
如果从using
命名空间(特别是在命名空间范围和/或头文件中)导入名称的std
指令通常被认为是一种不好的做法,因为它很容易导致命名冲突,请考虑以下程序:
namespace A { void foo() { } }
namespace B { void foo() { } }
int main()
{
using namespace A;
using namespace B;
foo();
}
编译器应如何解决对foo()
的调用?好吧,它不会。这是不明确的,因为A::foo()
和B:foo()
现在都可以称为不合格的foo()
。
如果std
命名空间和全局命名空间(或您拥有using
指令的任何其他命名空间)中存在具有相同名称的实体,则可能存在由于名称冲突导致的歧义出现。
在您的特定情况下,using
指令,例如:
using namespace std;
不太可能与您的tcp
声明引入的名称using
发生冲突(请注意,using
声明仅导入一个特定名称,并且因此,最好)。
然而,它仍然被认为是糟糕的编程风格,你不应该这样做,无论你是否已经有其他using
指令或using
声明。
答案 1 :(得分:2)
是的,他们可以。在这种情况下,编译器无法解析正确的命名空间。解决方案是使用前缀(例如std::
)。
您还可以将using namespace
关键字放在函数或其他块中,这样命名空间就不会在它之外使用:
void foo()
{
using namespace ns;
} // ns won't be used after this
此外,名称空间使用可以限制为标题:
namespace ns
{
#include "ns.h"
}
但是,将命名空间限制为标题是而不是,因为它在许多情况下会导致问题。
答案 2 :(得分:0)
其他答案很好地解释了当您有两个或更多using namespace
指令时如何解决歧义,但值得指出的是,如果你有这种情况则情况会有所不同using
声明从名称空间中提取两个或多个特定名称,如下所示:
namespace A { void foo() { } }
namespace B { void foo() { } }
int main()
{
using A::foo;
using B::foo;
return 0;
}
以上始终是编译错误,即使曾经使用foo
也没有。这是因为using
声明,顾名思义,实际上声明在其封闭范围内的名称是某个其他命名空间中名称的别名。这与using namespace
指令形成鲜明对比,只有在其封闭范围内使名称可用而不实际声明任何新名称。
如果您真的想要,可以像这样解决上述代码:
using fooa = A::foo;
using foob = B::foo;
但是,using
声明通常应该被避免,因为它们还有一些其他的语义意外,它们会以意想不到的,微妙的,有时无法察觉的方式咬你。异常是using
派生类中的基类成员,这通常是正常的,但通常不是必需的。