Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting std::complex<double> to pass std::is_floating_point test

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 doubles as well) are allowed as template instantiations, but nothing else?

like image 980
user14717 Avatar asked Aug 17 '14 00:08

user14717


People also ask

How do you test if a type is a floating point?

Tests if type is floating point. The type to query. An instance of the type predicate holds true if the type Ty is a floating point type or a cv-qualified form of a floating point type, otherwise it holds false. A floating point type is one of float, double, or long double.

What is true and false in C++ STL?

True: if the type is a float. False: if the type is a not float value. Below programs illustrate the std::is_floating_point template in C++ STL:

Can a complex class of type float be explicit?

A complex number of type float. The explicit specialization of the class template complex to a complex class of type float differs from the class template only in the constructors it defines. The conversion from float to double is allowed to be implicit, but the less safe conversion from float to long double is required to be explicit.

What is is_floating_point in C++ STL?

The std::is_floating_point template of C++ STL is used to check whether the given type is a floating point value or not. It returns a boolean value showing the same.


1 Answers

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.

like image 62
T.C. Avatar answered Sep 29 '22 00:09

T.C.