Search code examples
c++c++20c++-concepts

C++20 concept for complex floating point types


I am trying to learn concepts in C++20 and I have a class that represents a data sample. I want to restrict this class to accept only floating point types, or complex floating point types but I can't seem to figure out how to handle complex values with concepts.

Without concepts this is simple, but it allows way too many other data types that I don't want to allow.

Example without concepts:

template <typename T>
class Sample
{
    // ...
};

int main()
{
    // This compiles
    Sample<double> s1;
    Sample<complex<double>> s2;

    // This also compiles (but I don't want it to!)
    Sample<int> s3;
    // This compiles as well (again, I don't want it to!)
    Sample<complex<int>> s4;
}

With concepts I can easily restrict it to just take floating point values but then it doesn't work with complex values.

template<floating_point T>
class Sample
{
    // ...
};

int main()
{
    // This compiles
    Sample<double> s1;
    Sample<float> s2;

    // This does NOT compile (but I do want it to!)
    Sample<complex<double>> s3;
}

How can I create a concept to restrict the template to work with both real and complex floating point values?


Solution

  • Here's one solution that uses a partial specialization to check if T is a specialization of std::complex for floating point types:

    template <typename T>
    struct is_complex : std::false_type {};
    
    template <std::floating_point T>
    struct is_complex<std::complex<T>> : std::true_type {};
    

    With this, you can write the concept:

    template <typename T>
    concept complex = std::floating_point<T> || is_complex<T>::value;
    

    Here's a demo.