是否<algorithm>包括 <cmath>?
Does <algorithm> include <cmath>?
以下程序编译正确:
#include <algorithm>
int main(int argc, char *argv[]) {
return int(log(23.f));
}
(在g++4.9.2下,带有标志-std=c++11
)
该代码使用在<cmath>
上定义的函数log
。然而,它不包括报头<cmath>
,仅包括报头<algorithm>
。为什么g++
没有给出任何警告,并且正确编译了代码?
根据标准,某些标头确实包含其他标头。例如,<cinttypes>
包括<cstdint>
。请参阅此处的包含部分。关于<algorithm>
,没有关于它应该包括哪些其他头的声明(请参阅此处)。因此,结论是,<algorithm>
不需要包括<cmath>
,并且您的示例代码是不可移植的。它可能无法在其他C++实现上编译。
在C++11标准中,[res.on.headers]/1表示
C++标头可以包括其他C++标头。C++标头应提供其概要中出现的声明和定义AC++其概要中显示的标题(包括其他C++标题)应提供概要中出现的声明和定义其他标头的
现在考虑[算法.通用]/2:
标题
<algorithm>
简介#include <initializer_list> namespace std { // ......
<cmath>
未列出,且明显未包含在<initializer_list>
中。因此,您的程序不能保证在符合标准的实现上编译。一个人永远不应该依赖";隐含包含"-一般准则是包括使用实体的每个标头
例外情况例如<iostream>
,包括<ostream>
,这是从C++11开始保证的。
回答您的问题:
为什么g++没有给出任何警告,并且正确地编译了代码?
因为C++实现不需要,而且考虑到#include
的工作方式,实际上很难实现这个警告。虽然已经进行了尝试,但仍有一些问题尚未完全解决。
移动到不同的模型可以实现这种检查。然而,为了向后兼容性和允许最简单的转换,我使用的标准库的"模块化"恰好明确允许以前依赖间接包含的代码继续工作。
例如,您可以在libc++的模块映射中看到这一点;这些export *
行声明"该模块导入的任何模块也将导出。"也就是说,导入模块std.cmath的模块std.algorithm也将导出,因此任何导入std.algarithm的人都可以访问std.cmath.
对于新代码,如果可以关闭这些"遗留导出",那将是非常好的,但对于预先存在的大型项目,能够打开-fmodule并使项目在没有更改的情况下工作是非常好。
使用clang的libc++模块实现,并修改模块映射文件以删除不可移植的间接包含行为,clang报告了这样的错误,如:
main.cpp:5:16:错误:"log"的声明必须从模块"Darwin.C.math"导入,然后才需要
return int(log(23.f)); ^
/usr/include/math.h:387:15:注意:前面的声明在这里
extern double log(double); ^
生成1个错误。
libc++<algorithm>
不包括<cmath>
,所以我使用了<random>
。否则,产生上述内容的来源与您显示的内容相同。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中