在将一些代码从VS2013移植到GGC 4.9和Clang 3.5(使用libc ++)时,我遇到了编译失败的问题。代码的要点是
#include <cmath>
struct Foo
{
operator double() const { return( 101.0 ); } // Implicit conversion to double
};
int main( int, char** )
{
Foo foo;
std::exp( foo ); // Compiles
std::isfinite( foo ); // Does not
return( 0 );
}
我认为isfinite
调用无法编译,因为cmath中的isfinite
函数的返回类型声明为:
typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
并且由于Foo
不是is_arithmetic
,isfinite
会从重载集中删除。 isfinite
的朋友isnan
也是如此。所以我的问题是这是否是预期的。
标准是否要求isfinite
等函数的参数实际上直接double
或float
,而不是隐式转换为它们?
另外,我有点不确定为什么std::is_arithmetic
不是std::is_floating_point
,is_arithmetic
不是isfinite
对整数有误?
作为一个额外的问题,指定像 is_convertible_to_floating_point 这样的约束的最佳方法是什么?
答案 0 :(得分:5)
§26.8[c.math] / p10-11:
分类/比较函数的行为与C相同 具有7.12.3,Classification中定义的相应名称的宏 宏,和7.12.14,C标准中的比较宏。每 函数为三种浮点类型重载,如下所示:
// other functions omitted bool isfinite(float x); bool isfinite(double x); bool isfinite(long double x);
此外,还应有足够的额外过载来确保:
- 如果对应于double参数的任何算术参数具有类型
long double
,则所有算术参数对应于double
个参数有效地转换为long double
。- 否则,如果对应于
double
参数的任何算术参数具有类型double
或整数类型,则所有算术 对应于double
参数的参数被有效地转换为double
。- 否则,与
醇>double
参数对应的所有算术参数都具有类型float
。
我提交了一个针对libc ++的错误。