有一种情况(尽管比较少见)在使用的形式确实会有所不同,你需要使用的形式是using namespace foo
,并且最常用于std
命名空间(即在其中写using namespace std;
)。
最明显的例子是,你正在为用户定义的类型编写排序算法。有可能会应用于用户还定义了自己的swap
的类型。
你遇到了这样的情况:如果用户定义了swap
,则想使用他们的swap
,但如果他们没有定义,则希望使用std::swap
。如果直接在代码中使用std::swap
,那么即使该类型有其自己定义的交换函数,仍将使用std::swap
。相反,如果直接指定了特定类型的交换函数,并且未提供函数,则你的代码将无法编译。
为了解决这个问题,可以采取以下措施:
using namespace std;
template <class Iter>
void my_sort(Iter first, Iter last) {
if (*last < *first)
swap(*first, *last);
}
这将会为特定于正在比较的类型的交换找到一个(即,在与该类型相同的命名空间中定义的
swap
),如果有的话(通过参数依赖查找),并且对于该类型未定义任何一个,它将使用
std::swap
(通过
using namespace std;
)。
这可能会影响性能 - 如果他们为其类型编写了一个专门的交换,您通常可以预期这是因为这样做,他们可以提供更好的性能。这意味着明确指定
std::swap
可能有效,但可能会导致较差的性能。
否则,这几乎完全是方便和可读性的问题 - 我大多数情况下喜欢给出全名(例如
std::swap
),除非在上面的情况下(在我编写代码的时候),至少有两种可能性可能更受欢迎,我想给编译器足够的自由来选择正确的方法。
我发现使用声明/指令的另一个有用的时间是当命名空间被嵌套得非常深时。 Boost(一个明显的例子)有一些名称,如果每次都使用完全限定名称,那将会太长而不便于使用。这对于(现在,幸运的是,大部分已经过时的)Boost Lambda库尤其如此,其中您使用像
_1
这样的占位符,如果您坚持使用完全限定名称,那将变成类似于
boost::lambda::placeholders::_1
的东西(但我从记忆中得出,所以可能部分错误),这将击败使用lambda库的主要目的。
using namespace std;
也是一个安全漏洞。 - Adri C.S.std::swap
,但最好让答案更好地解释)可以帮助您在自己的命名空间中使用其他人提供的函数。std::
,那么可能会很繁琐。但它们之间没有任何性能差异,它们只涉及名称解析,并且不会“编译成实际代码”。