2014-12-06 2 views
5

VS2013에서 GGC 4.9 및 Clang 3.5 (libC++ 사용)의 일부 코드를 이식 할 때 컴파일 오류가 발생했습니다. 코드의 요점은 내가 cmath의 isfinite 연료 소모량이 형식을 반환로 선언이 때문에 isfinite 호출이 컴파일되지 않습니다 생각SFINAE std :: isfinite 및 유사한 기능을 사용하여 std :: is_arithmetic

#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); 
} 

입니다 :

typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type 

Foois_arithmetic하지 않기 때문에, isfinite이 제거됩니다 과부하 세트로부터. 같은 친구의 isfiniteisnan 같은 사실입니다. 그래서 내 질문은 이것이 예상되는지 여부입니다.

표준에서는 isfinite과 같은 함수의 인수가 실제로 직접 double 또는 float과 같이 암시 적으로 변환 가능하도록 요구합니까?

또한 std::is_arithmetic이 아닌 이유는 무엇입니까? std::is_floating_point이 아니며 is_arithmeticisfinite을 정수로 나타냅니다.

추가 질문으로 제약 조건을 지정하는 가장 좋은 방법은 입니다. is_convertible_to_floating_point?

+1

C++ 11 ['std :: exp'] (http://en.cppreference.com/w/cpp/numeric/math/exp)도 부동 소수점 유형뿐만 아니라 정수형도 허용합니다. –

+0

그리고 문제를 해결하기 위해 ['std :: is_arithmetic'] (http://en.cppreference.com/w/cpp/types/is_arithmetic)의 특수화를 클래스에 쉽게 추가 할 수 있습니다. –

+2

@JoachimPileborg 불가능합니다. 표준 라이브러리 유형 특성 ('std :: common_type' 제외)을 전문으로하는 것은 UB입니다. –

답변

5

§26.8 [c.math]/p10-11 :

The classification/comparison functions behave the same as the C macros with the corresponding names defined in 7.12.3, Classification macros, and 7.12.14, Comparison macros in the C Standard. Each function is overloaded for the three floating-point types, as follows:

// other functions omitted 
bool isfinite(float x); 

bool isfinite(double x); 

bool isfinite(long double x); 

Moreover, there shall be additional overloads sufficient to ensure:

  1. If any arithmetic argument corresponding to a double parameter has type long double , then all arithmetic arguments corresponding to double parameters are effectively cast to long double .
  2. Otherwise, if any arithmetic argument corresponding to a double parameter has type double or an integer type, then all arithmetic arguments corresponding to double parameters are effectively cast to double .
  3. Otherwise, all arithmetic arguments corresponding to double parameters have type float .

내가 libc에 대한 버그를 제출할 것 ++.

+0

GCC에 적용됩니다. libstdC++ 또한 – goneskiing

+0

@ goneskiing [libstdC++에 대해 테스트했을 때] 잘 작동합니다 (http://coliru.stacked-crooked.com/a/cb0d355028099712). –

+0

커맨드 라인 "gcc foo.cpp"와 함께 우분투 14.10에서 GCC 4.9.1 (일반 우분투 패키지)를 사용하고 있습니다 : "오류 : 'isfinite (Foo &)'호출에 맞는 함수가 없습니다 ...". 4.8을 사용하고 있는데 cmath 헤더를 보면 꽤 다른 것처럼 보입니다. – goneskiing

관련 문제