为什么即使我“使用命名空间 std;”,我仍然能够使用 std 命名空间中的名称?

Why am I able to use the names in the std namespace even though I'm "using namespace std;"?

提问人:Amirreza A. 提问时间:4/29/2021 更新时间:4/29/2021 访问量:218

问:

算法头文件中不是已经有 max 函数了吗? 通过,我将函数导入全局命名空间(它接受参数,在这种情况下,两者都是整数,所以它不应该是重载)。using namespace std;

那么为什么没有任何命名冲突呢?

#include <iostream>
#include <algorithm>

using namespace std;

int max(int a, int b)
{
    return (a > b) ? a : b;
}

int main()
{
    cout << max(5, 10) << endl;
}
C++ 命名空间 std

评论

2赞 doctorlove 4/29/2021
您的签名与 std::max 版本不同,因此您提供了重载
1赞 Peter 4/29/2021
您已显式提供了 in 全局命名空间的重载,其参数与 in 的调用完全匹配。在选择候选函数以匹配该调用时,该重载优先于任何模板化函数,例如 。此外,不会将函数“导入”到全局命名空间中。它使编译器使用 名称 in 作为候选项。 确实提供了要匹配的候选项,但您提供的重载也是如此,并且根据语言规则,是首选匹配项。max()max()main()std::max()using namespace stdstd::max()stdstd:max()max(5,10)
1赞 Riot 2/18/2023
这个问题很好地证明了为什么通常是一个可怕的想法。using namespace std

答:

5赞 songyuanyao 4/29/2021 #1

那么为什么没有任何命名冲突呢?

您正在声明一个非模板,而 std::max 是一组重载的函数模板,因此它们都重载。在全局命名空间中声明的非模板版本在这里的重载解析中被选中。max

如果隐式,则确定 F1 是比 F2 更好的函数 F1 的所有参数的转换并不比隐式参数差 F2 的所有参数的转换,以及

...

  1. 或者,如果不是这样,F1 是非模板函数,而 F2 是 模板专项课程

...

5赞 M.M 4/29/2021 #2

通过我将函数导入全局命名空间using namespace std

这是一个常见的误解。不导入任何内容。实际上,将指令放在全局命名空间中意味着,当在全局命名空间中查找名称时,该名称也会在命名空间中查找。using namespace std;std

该函数仍在命名空间中,它不在全局命名空间中。std::maxstd

您的声明很好,因为您声明哪个是单独的实体。max::maxstd::max

进行非限定函数调用时,将在全局命名空间中查找该名称,并在 中查找。maxnamespace std

这两种查找的结果都会导致一个重载集,该重载集由调用 和 的函数的所有签名组成。::maxstd::max

然后,重载解析从为所提供的参数设置的重载集中选择最佳匹配项,结果证明这是一个更好的匹配项,因为在所有其他条件相同的情况下,非模板函数比函数模板匹配得更好。::max