Ho appena eseguito un errore di compilazione durante il porting di codice da VS2013 a GGC 4.9 e Clang 3.5 (utilizzando libC++). Il nocciolo del codice èSFINAE std :: isfinite e funzioni simili utilizzando 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);
}
Credo che la chiamata isfinite
non viene compilato perché il isfinite
funtion in cmath ha tipo restituito dichiarato come:
typename std::enable_if<std::is_arithmetic<_A1>::value, bool>::type
e perché Foo
non è is_arithmetic
, isfinite
viene rimosso dal set di sovraccarico. Lo stesso vale per gli amici di isfinite
come isnan
. Quindi la mia domanda è se questo è previsto.
Lo standard richiede che gli argomenti per funzioni come isfinite
come effettivamente direttamente double
o float
anziché essere implicitamente convertibili a loro?
Anche io sono un po 'incerto il motivo per cui è std::is_arithmetic
non std::is_floating_point
, non implica is_arithmetic
isfinite
su interi?
Come domanda aggiuntiva qual è il modo migliore per specificare un vincolo come is_convertible_to_floating_point?
Poiché C++ 11 ['std :: exp'] (http://en.cppreference.com/w/cpp/numeric/math/exp) accetta anche tipi interi, non solo i tipi a virgola mobile. –
E per risolvere il tuo problema, puoi facilmente aggiungere una specializzazione di ['std :: is_arithmetic'] (http://en.cppreference.com/w/cpp/types/is_arithmetic) per la tua classe. –
@JoachimPileborg No non puoi. Specializzare un tratto di tipo libreria standard (eccetto 'std :: common_type') è UB. –