如何识别模板参数是否是std :: complex?

Soo*_*Soo 4 c++ templates typechecking complextype c++11

如何识别模板参数是否是std::complex?我想要一个支持所有数据类型的通用方法,如float,double,int等.我知道使用std :: is_same我可以专门检查给定的类型,例如std::complex<float>.但在这里我需要一个通用的方法.

Fra*_*ank 10

这可以使用部分模板专业化来完成.

首先定义一个默认为false的catch-all模板:

template<typename T>
struct is_complex_t : public std::false_type {};
Run Code Online (Sandbox Code Playgroud)

然后为符合条件的类型提供重载:

template<typename T>
struct is_complex_t<std::complex<T>> : public std::true_type {};
Run Code Online (Sandbox Code Playgroud)

我还想添加一个实用程序函数:

template<typename T>
constexpr bool is_complex() { return is_complex_t<T>::value; }
Run Code Online (Sandbox Code Playgroud)

编辑:对于c ++ 14及更高版本,此实用程序函数不需要或无用,因为std :: integral_type实现了operator().

用法:

bool int_is_complex = is_complex<int>(); //false
bool complex_is_complex = is_complex<std::complex<float>>(); //true
Run Code Online (Sandbox Code Playgroud)


W.F*_*.F. 4

据我了解您的问题,您正在寻找一种通用方法的实现来测试给定类型是否是给定模板模板类型的专业化。这可以使用类模板来完成,有点像弗兰克的回答。我将向您展示专业化的补充方法 - 具有函数重载的模板类型别名:

#include <type_traits>
#include <complex>
#include <iostream>

template <template <class...> class TT, class... Args>
std::true_type is_tt_impl(TT<Args...>);
template <template <class...> class TT>
std::false_type is_tt_impl(...);

template <template <class...> class TT, class T>
using is_tt = decltype(is_tt_impl<TT>(std::declval<typename std::decay<T>::type>()));

int main() {
    static_assert(is_tt<std::complex, std::complex<int>>::value, "!");
    static_assert(is_tt<std::complex, std::complex<float>>::value, "!");
    static_assert(!is_tt<std::complex, float>::value, "!");
}
Run Code Online (Sandbox Code Playgroud)

[现场演示]

您可以按如下方式利用该特征:

#include <type_traits>
#include <complex>
#include <iostream>

//complementary approach to specialization one would be to use function overloading
template <template <class...> class TT, class... Args>
std::true_type is_tt_impl(TT<Args...>);
template <template <class...> class TT>
std::false_type is_tt_impl(...);

template <template <class...> class TT, class T>
using is_tt = decltype(is_tt_impl<TT>(std::declval<typename std::decay<T>::type>()));

template <class T>
typename std::enable_if<is_tt<std::complex, T>::value>::type print(T t) {
    std::cout << "(" << t.real() << "," << t.imag() << ")" << std::endl;
}

template <class T>
typename std::enable_if<!is_tt<std::complex, T>::value>::type print(T t) {
    std::cout << t << std::endl;
}


int main() {
    print(std::complex<int>(1, 2));
    print(std::complex<double>(1.5, 2.5));
    print(5.5);
}
Run Code Online (Sandbox Code Playgroud)

(1,2)
(1.5,2.5)
5.5

[现场演示]