提供`T=std::complex<Q>`时如何避免嵌入`std::complex`?
How to avoid embedded `std::complex` when providing `T=std::complex<Q>`?
对于多项式方程求解器,最好将其模板化为任何可用类型:
template <class number, int degree>
class PolynomialEquation
{
public:
private:
array<number, degree+1> myEquation;
array<complex<number>, degree> equationResult;
};
这允许,例如,double
in ℝ 用于输入,结果为 std::complex<double>
in ℂ(我们知道从 2 阶及以上,方程的解通常落入ℂ,例如:x^2+1 ).
但是,方程式的输入也可以是 std::complex
。在这种情况下,myEquation
的类型应该是复数,但 equationResult
不应该是 std::complex<complex<T>>
,而只是 T
.[=23= 类型的普通复数]
问题:
方程带std::complex
时,如何让equationResult
的类型成为std::complex
的子类型?
是否有 std::is_floating_point
等同于 std::is_complex_number?
您可以创建一个特征,例如:
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;
};
我认为没有检查类型是否为复数的特征,但创建复数应该相对容易(也是 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>
}
这是 @W.F.
的 C++14 单行代码替代品
using Complex = typename std::conditional<std::is_arithmetic<T>::value, std::complex<T>, T>::type;
假设如果它不是算术类型,那么它应该是复数。如果您不想彻底,则需要确保 T 是算术(甚至浮点)或复数。您需要将其与@W.F 混合使用。答案。
我有一个多项式 class,其中我可能需要实数系数和复数 x(以及实数、实数和复数、复数)。我做了一个 is_complex:
/**
* Introspection class to detect if a type is std::complex.
*/
template<typename _Tp>
struct is_complex : public std::false_type
{ };
/**
* Introspection class to detect if a type is std::complex.
*/
template<>
template<typename _Tp>
struct is_complex<std::complex<_Tp>> : public std::true_type
{ };
/**
* Introspection type to detect if a type is std::complex.
*/
template<typename _Tp>
using is_complex_t = typename is_complex<_Tp>::type;
/**
* Introspection variable template to detect if a type is std::complex.
*/
template<typename _Tp>
constexpr bool is_complex_v = is_complex<_Tp>::value;
此外,无论输入是标量还是复数,我都使用工具来提取标量类型,因此我可以使用数字限制工具,例如:
template<typename Tp>
struct num_traits
{
using __value_type = Tp;
};
template<>
template<typename Tp>
struct num_traits<std::complex<Tp>>
{
using __value_type = typename std::complex<Tp>::value_type;
};
template<typename Tp>
using num_traits_t = typename num_traits<Tp>::__value_type;
我可以这样使用:
using Val = num_traits_t<Ret>;
constexpr auto eps = std::numeric_limits<Val>::epsilon();
并随后为实数和复数输入构建收敛测试。
对于多项式方程求解器,最好将其模板化为任何可用类型:
template <class number, int degree>
class PolynomialEquation
{
public:
private:
array<number, degree+1> myEquation;
array<complex<number>, degree> equationResult;
};
这允许,例如,double
in ℝ 用于输入,结果为 std::complex<double>
in ℂ(我们知道从 2 阶及以上,方程的解通常落入ℂ,例如:x^2+1 ).
但是,方程式的输入也可以是 std::complex
。在这种情况下,myEquation
的类型应该是复数,但 equationResult
不应该是 std::complex<complex<T>>
,而只是 T
.[=23= 类型的普通复数]
问题:
方程带std::complex
时,如何让equationResult
的类型成为std::complex
的子类型?
是否有 std::is_floating_point
等同于 std::is_complex_number?
您可以创建一个特征,例如:
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;
};
我认为没有检查类型是否为复数的特征,但创建复数应该相对容易(也是 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>
}
这是 @W.F.
的 C++14 单行代码替代品using Complex = typename std::conditional<std::is_arithmetic<T>::value, std::complex<T>, T>::type;
假设如果它不是算术类型,那么它应该是复数。如果您不想彻底,则需要确保 T 是算术(甚至浮点)或复数。您需要将其与@W.F 混合使用。答案。
我有一个多项式 class,其中我可能需要实数系数和复数 x(以及实数、实数和复数、复数)。我做了一个 is_complex:
/**
* Introspection class to detect if a type is std::complex.
*/
template<typename _Tp>
struct is_complex : public std::false_type
{ };
/**
* Introspection class to detect if a type is std::complex.
*/
template<>
template<typename _Tp>
struct is_complex<std::complex<_Tp>> : public std::true_type
{ };
/**
* Introspection type to detect if a type is std::complex.
*/
template<typename _Tp>
using is_complex_t = typename is_complex<_Tp>::type;
/**
* Introspection variable template to detect if a type is std::complex.
*/
template<typename _Tp>
constexpr bool is_complex_v = is_complex<_Tp>::value;
此外,无论输入是标量还是复数,我都使用工具来提取标量类型,因此我可以使用数字限制工具,例如:
template<typename Tp>
struct num_traits
{
using __value_type = Tp;
};
template<>
template<typename Tp>
struct num_traits<std::complex<Tp>>
{
using __value_type = typename std::complex<Tp>::value_type;
};
template<typename Tp>
using num_traits_t = typename num_traits<Tp>::__value_type;
我可以这样使用:
using Val = num_traits_t<Ret>;
constexpr auto eps = std::numeric_limits<Val>::epsilon();
并随后为实数和复数输入构建收敛测试。