【发布时间】:2014-12-06 21:02:08
【问题描述】:
在将一些代码从 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 会从重载集中移除。喜欢isnan的isfinite的朋友也是如此。所以我的问题是这是否是预期的。
标准是否要求像 isfinite 这样的函数的参数实际上直接直接 double 或 float 而不是隐式转换为它们?
我也有点不确定为什么std::is_arithmetic 不是std::is_floating_point,is_arithmetic 不是在整数上暗示isfinite?
作为一个额外的问题,指定像 is_convertible_to_floating_point 这样的约束的最佳方法是什么?
【问题讨论】:
-
由于 C++11
std::exp也接受整数类型,而不仅仅是浮点类型。 -
为了解决您的问题,您可以轻松地为您的班级添加
std::is_arithmetic的专业化。 -
@JoachimPileborg 不,你不能。专用于标准库类型特征(
std::common_type除外)的是 UB。 -
标准规定应该有三个重载签名分别采用
float、double和long double。我会提交一个错误。