2014-12-06 44 views
5

我剛剛遇到編譯失敗時,從VS2013一些代碼移植到GGC 4.9和Clang 3.5(使用libC++)。代碼的要點是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); 
} 

我相信isfinite調用不會編譯,因爲isfinite funtion在CMATH有返回類型聲明爲:

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

因爲Foois_arithmeticisfinite被刪除從超載設置。 isfinite的朋友也是如此,例如isnan。所以我的問題是這是否是預期的。

標準是否要求像isfinite這樣的函數的參數實際上是直接doublefloat而不是被隱式轉換爲它們?

另外我有點不確定爲什麼是std::is_arithmetic不是std::is_floating_point,不是is_arithmetic暗示isfinite整數?

作爲一個額外的問題什麼是指定約束的最佳方式,如is_convertible_to_floating_point

+1

由於C++ 11 ['std :: exp'](http://en.cppreference.com/w/cpp/numeric/math/exp)也接受整數類型,所以不僅是浮點類型。 – 2014-12-06 21:13:47

+0

爲了解決您的問題,您可以輕鬆地爲您的課程添加['std :: is_arithmetic'](http://en.cppreference.com/w/cpp/types/is_arithmetic)專業化。 – 2014-12-06 21:14:54

+2

@JoachimPileborg不,你不能。專門的標準庫類型特徵(除了'std :: common_type')是UB。 – 2014-12-06 21:20:33

回答

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 2014-12-06 21:48:09

+0

@goneskiing當我[測試針對libstdC++](http://coliru.stacked-crooked.com/a/cb0d355028099712)時,它工作正常。 – 2014-12-06 21:50:57

+0

我在Ubuntu 14.10上使用GCC 4.9.1(普通Ubuntu包),命令行爲「gcc foo.cpp」給出了「錯誤:沒有與'isfinite(Foo&)'...」調用的匹配函數。你使用4.8,看着cmath頭,它看起來很不一樣。 – goneskiing 2014-12-06 22:04:34

相關問題