2016-07-28 33 views
6

对于多项式方程求解,这将是巨大的模板它有可用的任何类型:如何在提供`T = std :: complex <Q>`时避免嵌入`std :: complex`?

template <class number, int degree> 
class PolynomialEquation 
{ 
public: 

private: 
    array<number, degree+1> myEquation; 
    array<complex<number>, degree> equationResult; 
}; 

这允许,例如,在ℝdouble用于输入,结果是std::complex<double>在ℂ中(我们知道从2级开始,方程的解决方案通常落入ℂ,例如:x^2 + 1)。

但是,等式的输入也可以是std::complex。在这种情况下,myEquation的类型应该很复杂,但equationResult不应该是std::complex<complex<T>>,而只是T类型的正常复数。

问题:

如何使equationResult类型是子类型的std::complex当方程提供std::complex

有没有像std :: is_complex_number一样的std::is_floating_point

回答

7

您可以创建一个特征,是这样的:

template <typename T> 
struct to_complex { 
    using type = std::complex<T>; 
}; 

template <typename T> 
struct to_complex<std::complex<T>> { 
    using type = std::complex<T>; 
}; 

然后

template <class number, int degree> 
class PolynomialEquation 
{ 
public: 

private: 
    array<number, degree+1> myEquation; 
    array<typename to_complex<number>::type, degree> equationResult; 
}; 
+1

也许我会称之为'poly_root_type_traits'或类似的东西 - 'to_complex'对于这件事背后的理由有点不清楚。 –

2

我不认为这是用于检查一个特点,如果该类型是一个复杂的号码,但应该比较容易创建一个(也可以替代实现Jarod的to_complex):

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

template <class T> 
struct is_complex_number: std::false_type { }; 

template <class T> 
struct is_complex_number<std::complex<T>>: std::true_type { }; 

template <class T> 
struct to_complex: std::conditional<is_complex_number<T>::value, T, std::complex<T>> { }; 

int main() { 
    std::cout << is_complex_number<float>::value << std::endl; // output: 0 
    std::cout << is_complex_number<std::complex<float>>::value << std::endl; // output: 1 
    typename to_complex<float>::type c; // decltype(c) == complex<float> 
    typename to_complex<std::complex<float>>::type d; // decltype(d) == complex<float> 
} 
+0

我想不出有什么办法可以在一行中使用std :: same,是吗?在type_traits中是否有东西来检查T是否是模板模板,并且它是否为U ? –

+0

@Benoît如果'V'是类型模板参数,可以用两个重载创建constexpr函数:'template constexpr bool is_template_template(){return false; } template