繁体   English   中英

为什么包括<map>导致在全局命名空间中定义 div 函数?

[英]Why does including <map> cause the div function to be defined in the global namespace?

考虑以下代码块:

void foo(){
  int a = div(1,2);
}

这通常不会编译,因为div函数尚未声明。 但是,如果我在代码前面加上#include <map> ,代码就会编译。 为什么map将标识符拉入全局命名空间,为什么特别是div函数? 有没有办法避免这种情况?

[麦克维]

#include <map>

void foo(){
  int a = div(1,2);
}

int main()
{
  foo();    
}

实时链接 - https://godbolt.org/z/Ye8rv4MTc

clang - <source>:4:7: error: no viable conversion from 'div_t' to 'int'

gcc - <source>:4:11: error: 'div' was not declared in this scope

MSVC - <source>(4): error C2440: 'initializing': cannot convert from 'div_t' to 'int'

任何 C++ 标准库头文件都允许包含任何其他 C++ 标准库头文件。

这些头文件之一是<cstdlib> ,它是<stdlib.h> C 标准库头文件的 C++ 版本,它声明了函数div_t div(int, int)

C 标准库头文件的 C++ 版本通常在std命名空间中声明所有实体。 然而,该标准允许实现允许他们首先在全局命名空间中声明实体,然后通过using声明将它们导入std命名空间。

因此,如果您完全包含任何 C++ 标准库头文件,您必须期望 C 标准库中的任何实体都可以在全局命名空间中声明。 div_t div(int, int)就是其中之一。

然而,所有这些都是未指定的行为。 如果仅包含<map> ,则无法保证div_t div(int, int)将被声明(在全局命名空间或std中)。

如果名称与您要声明自己的某些实体冲突,则解决方案是将您自己的所有东西(除main )放入您自己的命名空间。 这样,名称查找将更喜欢您在命名空间内的声明,而不是全局命名空间中的声明。 无论如何都应该这样做。 全局命名空间中有许多潜在的陷阱,特别是其中有许多额外的保留标识符、名称、签名等。

不是答案,而是包含 msvc 的信息,因此它似乎确实被拉入了全局命名空间

1>main.cpp
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\map
1>Note: including file:  ...\VC\Tools\MSVC\14.32.31326\include\tuple
1>Note: including file:   ...\VC\Tools\MSVC\14.32.31326\include\compare
1>Note: including file:    ...\VC\Tools\MSVC\14.32.31326\include\bit
1>Note: including file:      ...\VC\Tools\MSVC\14.32.31326\include\xstddef
1>Note: including file:       ...\VC\Tools\MSVC\14.32.31326\include\cstdlib
1>Note: including file:        C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt\stdlib.h

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM