C++ std:: 并包括它们如何组合在一起?



>我很困惑。我写了一个名为hash((的函数,我正在使用命名空间std 咔嚓,咕噜咕噜和懒惰。

对"哈希"的错误引用不明确

我现在知道 std 中存在一个哈希函数:

所以我的问题是为什么编译器会抛出这个错误,因为我从未包含 functional.h?

是否有来自 std:: 的名称索引,以便我将来在编写自己的函数时可以避免使用这些名称,我在 google 上找不到任何东西?

我很困惑,因为 std 中何时知道"一切":为什么需要包含标头?我确定我错过了什么

也许我的头衔不是最好的,但我不知道更好。

#include <iostream>
using namespace std;
const int SIZE_TABLE = 10;
int hash(int x)
{
return x%SIZE_TABLE;
}
int main()
{
cout<<"hash 24 "<<hash(24)<<endl;
return 0;
}

编译器尝试获取正确的哈希函数。您的哈希函数在全局命名空间下实现,地址为 ::

::hash(1)

在正常情况下,编译器会使用此命名空间,如果您使用

hash(1)

但是你对编译说"嘿,伙计,也在 std::" 中搜索每个调用:

using namespace std;

所以他无法在

::hash(1)
and
std::hash(1)

全局范围内使用在头文件中是一个问题,因为将此指令导入到其他文件(包括头文件(中。

在 cpp 文件中,这是品味问题。我也不喜欢在 cpp 中使用它。

为什么编译器会抛出此错误,因为我从未包含functional.h?

using namespace std;

因为全局命名空间中有此内容,所以会污染全局命名空间

没有明确定义将多少符号引入全局命名空间。 允许标头包含其他标头,以及定义未记录的符号。

您还将自己的符号添加到同一命名空间。 任何全局符号都可能与命名空间std中定义的符号冲突。

教训:只要不要那样做,你就不会有这个问题。

第一步,不要这样做:using namespace std;.您正在提取标准库的所有名称(至少是直接和传递包含看到的名称(,碰巧std::hash是一回事 - 最终与您自己的hash发生冲突。

如果你拉入所有 std,而是用std::前缀明确引用 std 的东西,或者只是用类似using std::vector;的东西拉入你真正想要的东西(比如说std::vector(,那么你就不会有这个问题。

命名空间的存在是为了将具有相同名称的符号分隔到单独的域/框中。使用using namespace foo;会打败这一点。

具体回答为什么std::hash尽管没有直接包含其标头,但仍被拉入:您确实包含的其他标头包含它或包含其他标头,而这些标头又包含它,等等 - 传递包含。

最新更新