Я только что столкнулся с ошибкой компиляции при переносе некоторого кода из 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
не компилируется, потому что функция isfinite
в cmath имеет возвращаемый тип, объявленный как:
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?
std::exp
также принимает целочисленные типы, а не только типы с плавающей запятой. - person Some programmer dude   schedule 07.12.2014std::is_arithmetic
для вашего учебный класс. - person Some programmer dude   schedule 07.12.2014std::common_type
) — UB. - person T.C.   schedule 07.12.2014float
,double
иlong double
соответственно. Я бы зарегистрировал ошибку. - person T.C.   schedule 07.12.2014