I want the types double
, float
, complex<double>
and complex<float>
to pass a static_assert
condition. I figured static_assert(std::is_floating<T>::value, "some message")
would do the trick, but the complex types do not pass this test (at least under gcc-4.10).
What predicate would I add to make sure these four types (and perhaps long double
s as well) are allowed as template instantiations, but nothing else?
It is generally illegal to add specializations for standard library type trait classes, even for user-defined types. §20.10.2 [meta.type.synop]/p1:
The behavior of a program that adds specializations for any of the class templates defined in this subclause is undefined unless otherwise specified.
Currently, the only type trait class that users are allowed to add specializations for is std::common_type
, if at least one template parameter in the specialization is a user-defined type (§20.10.7.6 [meta.trans.other], Table 57).
You need to write your own trait, which isn't hard:
template<class T>
struct is_complex_or_floating_point : std::is_floating_point<T> { };
template<class T>
struct is_complex_or_floating_point<std::complex<T>> : std::is_floating_point<T> { };
Demo.
If you're willing to use Boost.TypeTraits, they provide boost::is_complex
for use with std::complex
.
#include <complex>
#include <type_traits>
#include <boost/type_traits.hpp>
int main()
{
static_assert(std::is_floating_point<float>::value, "some message");
static_assert(std::is_floating_point<double>::value, "some message");
static_assert(boost::is_complex<std::complex<float>>::value, "some message");
static_assert(boost::is_complex<std::complex<double>>::value, "some message");
}
来源:https://stackoverflow.com/questions/25345206/getting-stdcomplexdouble-to-pass-stdis-floating-point-test