I've been trying to define an auxiliary class to help me work with template methods in which I would like a generic implementation both for complex and real types.
That has been my attempt so far:
#include<type_traits>
#include<complex>
template<class T>
struct is_complex{ static constexpr bool value = false;};
template<class T>
struct is_complex<std::complex<T>> :
std::integral_constant<bool,
std::is_integral<T>::value ||
std::is_floating_point<T>::value>{};
template<class T>
struct is_arithmetic:
std::integral_constant<bool,
std::is_integral<T>::value ||
std::is_floating_point<T>::value ||
is_complex<T>::value>{};
template<class T,
typename std::enable_if_t<is_arithmetic<T>::value,int> =0>
struct real_type {typedef T type;};
template<class T>
struct real_type<typename std::complex<T>>{typedef T type;};
I want to get something like
typename real_type<std::complex<double>> myVar1;//myVar1 is double
typename real_type<double> myVar2;//myVar2 is double
I was able to make it work as long as I didn't care that non-arithmetic types also had real_type<T>::type. But now that I have added this additional constraint, I cannot make it work and I don't really see why.
To clarify: I would like that calls like real_type<std::string>::type would generate compile-time errors. I want these calls to be valid only to arithmetic (including complex) and integral types.
The compiler error of my latest attempt was:
non-type template argument specializes a template parameter with dependent type 'typename std::enable_if_t<is_arithmetic<T>::value, int>' (aka 'typename enable_if<is_arithmetic<T>::value, int>::type')
But I don't know how to deal with it. If this information is useful, I have access to compilers supporting C++17.