2016-07-28 15 views
6

Đối với một giải phương trình đa thức, nó sẽ là tuyệt vời để template nó có bất kỳ loại có sẵn:Làm thế nào để tránh nhúng `std :: complex` khi cung cấp` T = std :: complex <Q> `?

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

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

này cho phép, ví dụ, double trong ℝ được sử dụng cho đầu vào, và kết quả là std::complex<double> trong ℂ (chúng ta biết rằng từ mức độ 2 trở lên, giải pháp cho phương trình thường rơi vào ℂ, ví dụ: x^2 + 1).

Nhưng, đầu vào cho phương trình cũng có thể là std::complex. Trong trường hợp này, loại myEquation phải phức tạp, nhưng equationResult KHÔNG được là std::complex<complex<T>>, nhưng chỉ là số phức hợp bình thường của loại T.

Câu hỏi:

Làm thế nào để làm cho các loại equationResult là sub-type của std::complex khi phương trình được cung cấp với std::complex?

Có một số std::is_floating_point tương đương như tiêu chuẩn :: is_complex_number?

Trả lời

7

Bạn có thể tạo ra một đặc điểm, một cái gì đó như:

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>; 
}; 

Và sau đó

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

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

Có lẽ tôi sẽ gọi nó là 'poly_root_type_traits' hoặc một cái gì đó tương tự -' to_complex' là một chút không rõ ràng về lý do đằng sau điều này. –

2

Tôi không nghĩ rằng có một đặc điểm để kiểm tra nếu loại là một số phức nhưng nó nên tương đối dễ dàng để tạo một (cũng là cách triển khai thay thế cho Jarod's 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

Tôi không thể nghĩ ra bất kỳ cách nào để sử dụng std :: giống nhau trong một lớp lót, phải không?Có điều gì đó trong type_traits để kiểm tra nếu T là một mẫu template và nếu nó có dạng U ? –

+0

@ Benoît nếu 'V' là kiểu tham số mẫu có thể tạo hàm constexpr với hai lần nạp chồng:' mẫu constexpr bool is_template_template() {return false; } mẫu