这是libstdc中的一个bug,它随GCC一起提供。它不完全符合C17(as of v9.1.0 in June 2019)。Ubuntu默认使用的<cmath>版本上的版权声明说,它最后一次更新是在2016年。9.1.0版本确实有一个#if __cplusplus > 201402L部分,但它没有声明C17所需的标识符。There is an open bug report. 它从不在std::命名空间中声明expf或logf(也不声明cosf,sinf等),即使C17说它应该这样做。C++11 standard说,“在C中定义为函数的名称应定义为C++标准库中的函数”,并且“标准C库中使用外部链接声明的每个名称都保留给实现,以用作extern "C"链接的名称,无论是在namespace std中还是在全局命名空间中。从<cmath>直到P0175r1 in June 2016.提供的函数表中缺失这显然是一个疏忽,但GCC一直只在全局名称空间中提供它们。 libc++库声明了它们,所以用clang++ -std=c++17 -stdlib=libc++编译应该可以。您也可以在全局命名空间中使用#include <math.h>,或者使用重载的exp(),log()等。float参数。
3条答案
按热度按时间quhf5bfb1#
这是libstdc中的一个bug,它随GCC一起提供。它不完全符合C17(as of v9.1.0 in June 2019)。Ubuntu默认使用的
<cmath>
版本上的版权声明说,它最后一次更新是在2016年。9.1.0版本确实有一个#if __cplusplus > 201402L
部分,但它没有声明C17所需的标识符。There is an open bug report.它从不在
std::
命名空间中声明expf
或logf
(也不声明cosf
,sinf
等),即使C17说它应该这样做。C++11 standard说,“在C中定义为函数的名称应定义为C++标准库中的函数”,并且“标准C库中使用外部链接声明的每个名称都保留给实现,以用作extern "C"
链接的名称,无论是在namespace std
中还是在全局命名空间中。从<cmath>
直到P0175r1 in June 2016.提供的函数表中缺失这显然是一个疏忽,但GCC一直只在全局名称空间中提供它们。libc++库声明了它们,所以用
clang++ -std=c++17 -stdlib=libc++
编译应该可以。您也可以在全局命名空间中使用#include <math.h>
,或者使用重载的exp()
,log()
等。float参数。更新
截至2023年8月,libc++终于有了一个补丁,等待提交。
wj8zmpe12#
如果你
你会得到
因此,您可以只调用
std::exp
/std::log
,让编译器为您计算重载。如果你想调用一个不匹配的重载(例如double
变量上的float
重载),我发现在这些情况下添加static_cast
更显式和清晰:这是一个奇怪的结构,无论你怎么写它(例如。为什么
bla
不是一个float
开始开始?),将其隐藏在单字母函数名后缀中对任何人都没有帮助。pbgvytdp3#
GCC的
<cmath>
在全局命名空间中声明了函数expf
和logf
以及它们的C Library kin,而不是std::
。在std::
中,它声明了exp
和log
的重载,效果相同。