首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 ><algorithm>包括<cmath>吗?

<algorithm>包括<cmath>吗?
EN

Stack Overflow用户
提问于 2015-04-05 05:41:35
回答 3查看 1.7K关注 0票数 5

以下程序正确编译:

代码语言:javascript
复制
#include <algorithm>

int main(int argc, char *argv[]) {

    return int(log(23.f));

}

(在g++ 4.9.2下,标志为-std=c++11)

代码使用函数log,该函数是在<cmath>上定义的。但是,它不包括头<cmath>,只包括标头<algorithm>。为什么g++没有给出任何警告,并正确编译代码?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-05 11:04:28

在C++11标准中,res.on.Header/1声明

C++头可以包括其他C++头。C++标头应提供其概要中出现的声明和定义。在其概要中显示为包含其他C++标头的C++头应提供出现在这些其他标头摘要中的声明和定义。

现在考虑一下算法,一般/2:

标头<algorithm>概要 #包括命名空间std { // .

<cmath>没有列出,而且显然没有包括在<initializer_list>中。因此,您的程序不能保证在符合标准的实现上编译。绝不能依赖“隐式包含”--一般准则是包含使用实体的每一个标头。

异常是例如<iostream>,包括<ostream>,这在C++11之后就得到了保证。

票数 6
EN

Stack Overflow用户

发布于 2015-04-05 06:39:25

根据标准,一些标头确实包括其他的头。例如,<cinttypes>包括<cstdint>。请参见包含部分这里。关于<algorithm>,没有关于它应该包括哪些其他标头的声明(参见这里)。因此,结论是,<algorithm>不需要包含<cmath>,您的示例代码也不是可移植的。它可能无法在其他C++实现上编译。

票数 9
EN

Stack Overflow用户

发布于 2015-04-05 19:01:06

回答你的问题:

为什么g++没有给出任何警告,并正确编译代码?

因为C++实现不是必需的,而且考虑到#include的工作方式,实现这个警告实际上非常困难。尝试已经完成,但是有些问题还没有得到完全解决。

移动到不同模型可以启用这种检查。但是,为了保持向后兼容性和允许最容易的转换,我使用的标准库的“模块化”碰巧显式地允许以前依赖于间接包含的代码继续工作。

例如,在libc++的模块映射中可以看到这一点;这些export *行声明“由该模块导入的任何模块也被导出”,也就是说,导入模块std.cmath的模块std.algorithm也可以导出,因此任何导入std.algorithm的人都可以访问std.cmath。

对于新代码,如果可以关闭这些“遗留导出”,这将是非常好的,但是对于已经存在的大型项目来说,能够切换-fmodules并使项目工作不发生任何更改是非常好的。

使用clang使用libc++实现模块,并修改模块映射文件以删除不可移植的间接包含行为,clang报告如下错误:

main.cpp:5:16:错误:在需要“Darwin.C.math”之前,必须从模块“Darwin.C.math”导入“日志”声明 返回int(log(23.f));^ /usr/include/math.h:387:15:注意:前面的声明在这里是extern double log(double);^1错误生成。

libc++ <algorithm>不包括<cmath>,所以我使用了<random>。否则,产生上述结果的源与您所显示的相同。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29454488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档