Po prostu napotkałem awarię kompilacji podczas przenoszenia kodu z VS2013 do GGC 4.9 i Clang 3.5 (używając libC++). Istota kod jestSFNAE std :: isfinite i podobne funkcje używające 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);
}
wierzę wywołanie isfinite
nie kompiluje ponieważ isfinite
funtion w cmath ma Zwraca typ zadeklarowany jako:
typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
i dlatego Foo
nie jest is_arithmetic
, isfinite
zostanie usunięty z zestawu przeciążeniowego. To samo dotyczy znajomych isfinite
, takich jak isnan
. Więc moje pytanie brzmi, czy to jest oczekiwane.
Czy standard wymaga, aby argumenty dla funkcji takich jak isfinite
były faktycznie bezpośrednio double
lub float
, a nie były domyślnie dla nich wymienialne?
Również nie jestem pewien, dlaczego jest std::is_arithmetic
nie std::is_floating_point
, czy is_arithmetic
implikuje isfinite
na liczbach całkowitych?
Jako dodatkowe pytanie, jaki jest najlepszy sposób określenia ograniczenia takiego jak is_convertible_to_floating_point?
Ponieważ C++ 11 ['std :: exp'] (http://en.cppreference.com/w/cpp/numeric/math/exp) również przyjmuje typy integralne, nie tylko typy zmiennoprzecinkowe. –
I aby rozwiązać twój problem, możesz łatwo dodać specjalizację ['std :: is_arithmetic'] (http://en.cppreference.com/w/cpp/types/is_arithmetic) dla twojej klasy. –
@JoachimPileborg Nie, nie możesz. Specjalizacją standardowej cechy typu biblioteki (z wyjątkiem 'std :: common_type') jest UB. –