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?
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.