似乎gcc(尝试7.2.0和5.4.0)没有std::expf和std::logf-请参阅coliru sample。由于cppreference表示它们是在C ++ 11中添加的,因此我是否缺少某些gcc特定的宏,或者它们在gcc中总体上还是缺少的?
答案 0 :(得分:2)
这是GCC随附的libstdc ++中的错误。它不完全符合C ++ 17(as of v9.1.0 in June 2019)。 Ubuntu默认使用的<cmath>
版本的版权声明说它最近一次更新是在2016年。版本9.1.0确实有一个#if __cplusplus > 201402L
部分,但没有声明C所需的标识符。 ++ 17。 There is an open bug report.
即使C++17 says it shall.,它也不会在expf
命名空间内声明logf
或cosf
(也sinf
,std::
等)。 C++11 standard说:“在C中定义为函数的名称应在C ++标准库中定义为函数”,和“使用外部链接声明的标准C库中的每个名称都保留给实现,以用作在extern "C"
和全局命名空间中都具有namespace std
链接的名称。”然而,std::expf
等人。 <cmath>
提供的功能表中缺少这些功能,直到P0175r1 in June 2016.为止,这显然是一个疏忽,但是GCC始终只在全局名称空间中提供它们。
libc++库确实声明了它们,因此使用clang++ -std=c++17 -stdlib=libc++
进行编译应该可以。您也可以#include <math.h>
在全局名称空间中使用它们,或对浮点参数使用重载的exp()
,log()
等。
答案 1 :(得分:1)
如果您
#include <cmath>
您将获得
float exp ( float arg );
double exp ( double arg );
long double exp ( long double arg );
double exp ( IntegralType arg );
float log ( float arg );
double log ( double arg );
long double log ( long double arg );
double log ( IntegralType arg );
因此,您可以只调用std::exp
/ std::log
,然后让编译器为您找出重载。如果您想调用不匹配的重载(例如,float
变量上的double
重载),我发现在这些情况下添加static_cast
更为明确和明确:
double bla = ...;
return std::exp(static_cast<float>(bla));
无论用哪种方式编写,这都是一个奇怪的构造(例如,为什么bla
不是一个float
?),并且将其隐藏在单字母函数名称后缀中是没有用的任何人。
答案 2 :(得分:0)
要使g ++使用C ++ 11,您需要添加
-std=c++11
到编译器命令行。
例如:
g++ -o test -std=c++11 test.cc
答案 3 :(得分:0)
GCC的<cmath>
在函数中声明函数expf
和logf
以及它们的C库亲属。
全局名称空间,而不是std::
。在std::
中,将exp
和log
的重载声明为
同样的效果。