#include <iostream>
int main()
{
int value1 = 1, value2 = 10;
std::cout << "Min = " << std::min(value1,value2) <<std::endl;
std::cout << "Max = " << std::max(value1,value2)<< std::endl;
}
据我所知,min
和max
函数在<algorithm>
中定义。
如果我没有告诉预处理器包含<algorithm>
为什么代码仍然有效?
答案 0 :(得分:20)
最有可能的是,iostream
内的某些内容直接或间接包含了定义std::min
和std::max
的其他标题。 (也许algorithm
本身已包含在内。也许是一些用于实现C ++标准库的内部头文件。)
您不应该依赖此行为。如果你想要std :: min和std :: max。
,请加入algorithm
如果您习惯使用具有模块系统的语言,其中模块可以导入其他模块而不必强制从导入中导出任何内容(例如,Racket的模块系统),则此行为可能会造成混淆。
但是,回想一下,#include正在进行文本替换。处理#include行时,它将从.cpp文件中删除,并替换为它指向的文件的内容。
大多数编译器都可以选择转储运行预处理器的输出,以便您可以跟踪包含内容的内容。您在评论中对kmort的回答说您使用的是Visual Studio Express。使用Visual C ++编译器的preprocess a file to a file命令行是cl /P foo.cpp
。使用此输出,我们可以发现std::max
的定义来自特定于实现的标头xutility
。 (将插入符号放在文本“std:max”中并在Visual Studio中按F12会更快。: - ])
kmort还提到了/showIncludes
编译器开关。使用它,我们可以轻松追踪包含链。这是我跑步减少的输出。
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\iostream
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\istream
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ostream
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\ios
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocnum
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\streambuf
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xiosbase
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xlocale
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\stdexcept
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xstring
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0
Note: including file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xutility
答案 1 :(得分:2)
您使用的是哪种编译器?
我之前看过编译器对libc或libstdc ++中定义的常用项有点“宽容”。它将为您提供参考。换句话说,您不必告诉它与之链接,也不必包含标题。它只是有效。虽然我不会期望min()
和max()
的这一点,但这并不太令人惊讶。
这也可以通过其他一些标题包括您应该包含的标题,但不应该依赖它。而且我不认为在这种情况下会发生这种情况。
答案 2 :(得分:0)
为了补充上面的对话,我最近偶然发现了一个类似的问题。如果您在不包含 algorithm
标头的情况下执行 min/max 调用,它仍然可以正常运行。
std::min(value1, value2)
但是如果你在初始化列表上执行它(将所有变量放在 {...}
之间),如下所示,
std::min({value1, value2, value3})
编译器抛出一个参数不匹配错误。这很可能是因为函数覆盖无法捕获必须仅在 template constexpr T max (initializer_list il, Compare comp)
内定义的 algorithm.h
。正如其他人所回答的那样,基本的 template constexpr const T& max (const T& a, const T& b)
可能已包含在 iostream
内的某处。但我认为没有包含整个 algorithm
头文件,因为如果包含,上面的代码段也应该有效。