如何识别模板参数是否为std :: complex?
问题描述:
如何识别模板参数是否为std::complex
?我想要一个支持float,double,int等所有数据类型的通用方法。 我知道使用std :: is_same我可以特别检查给定类型,例如std::complex<float>
。 但在这里我需要一个通用的方法。如何识别模板参数是否为std :: complex?
答
正如我理解你的问题,你正在寻找一种通用方法的实现来测试给定类型是否是给定模板模板类型的特化。这可以使用类模板来完成,有点像Frank's answer。我将为您呈现互补的方式向专业化 - 模板类型别名与函数重载:
#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, "!");
}
您可以利用特点如下:
#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);
}
(1,2)
(1.5,2.5)
5.5
答
这可以使用部分模板专业化来完成。
首先定义一个包罗万象的模板默认为false:
template<typename T>
struct is_complex_t : public std::false_type {};
然后你符合你条件的类型提供过载:
template<typename T>
struct is_complex_t<std::complex<T>> : public std::true_type {};
我也想补充工具功能以及:
template<typename T>
constexpr bool is_complex() { return is_complex_t<T>::value; }
编辑:不需要此效用函数或有用与C++ 14及以上,因为std :: integral_type实现operator()。
用法:
bool int_is_complex = is_complex<int>(); //false
bool complex_is_complex = is_complex<std::complex<float>>(); //true
答
您可以基于你对tag分派技术解决方案。
它遵循最小,工作示例:
#include<complex>
#include<utility>
#include<iostream>
class C {
template<typename T>
void f(int, std::complex<T>) {
std::cout << "complex" << std::endl;
}
template<typename T>
void f(char, T &&t) {
std::cout << "something else" << std::endl;
}
public:
template<typename T>
void f(T &&t) {
f(0, std::forward<T>(t));
}
};
int main() {
C c;
c.f(0);
c.f(std::complex<float>{});
}
在这里,你必须能够接受几乎所有的东西,并在内部分发到正确的函数的一般方法f
。
模板专业化 – Danh
你想“专精”什么?添加一个具体的例子,你的文章没有足够的信息来回答。 – Holt