我写了一个模板类,应该适用于double和std :: complex。正如它所假设的那样,我的所有方法都在.hpp文件中。除了一个。我必须专门化一个方法,因为在某些地方我必须计算一个双的平方或std :: complex的范数。更明确的“双重专业化”(A):
double a(2.0);
double b(0.0);
b = a*a;
用于“复杂专业化”(B):
std::complex<double> a(2.0,3.0);
double b(0.0);
b = std::norm(a);
我的问题是:
有没有办法通过使用适用于double和complex的函数来避免这些特化? (因为std :: norm仅适用于复杂的......)
或唯一的解决方案是将专业化(A)的双重a转换为复合体,然后仅使用特化(B)作为通用模板(同时用于复合和复合)?
答案 0 :(得分:2)
您可以通过将自己的函数作为平方/范数包装器来最小化不同情况:
template <typename T>
double square_or_norm(T x);
template<>
inline double square_or_norm(double x) { return x * x; }
template <>
inline double square_or_norm(std::complex<double> x) { return norm(x); }
然后,在需要它的函数中使用它:
template <typename T>
T computation(T x) {
return some_code_with(x, square_or_norm(x));
}
答案 1 :(得分:1)
您可以定义两个函数模板重载(当涉及到函数模板时,重载通常比 specialization 更可取)称为{{1一个接受compute_norm()
,一个接受无约束类型。无约束模板将调用std::complex
,而受约束的模板将调用operator *
。
std::norm()
然后,您的通用代码可以使用#include <complex>
template<typename T>
double compute_norm(T t)
{ return t * t; }
template<typename T>
double compute_norm(std::complex<T> const& t)
{ return std::norm(t); }
和double
同时调用complex<double>
:
compute_norm()
例如,以下程序:
#include <iostream>
template<typename T>
void foo(T&& t)
{
// ...
double n = compute_norm(std::forward<T>(t));
std::cout << n << std::endl;
// ...
}
将输出:
int main()
{
double a(2.0);
foo(a);
std::complex<double> c(2.0, 3.0);
foo(c);
}
这是live example。
答案 2 :(得分:1)
如果您有一个符合标准的库,浮点类型的重载次数为std::norm
:
26.4.9 其他重载[cmplx.over]
以下函数模板应具有其他重载:arg norm conj proj imag real
额外的过载应足以确保:
- 如果参数的类型为long double,那么它将被有效地转换为复数。
- 否则,如果参数具有double类型或整数类型,则它有效地转换为complex&lt; 双&GT;
- 否则,如果参数的类型为float,那么它将被有效地转换为complex。
醇>
这应该有效(并在gcc 4.7.2上执行)
#include <complex>
#include <iostream>
int main()
{
std::complex<double> c {1.5, -2.0};
double d = 2.5;
std::cout << "|c| = " << std::norm(c) << '\n'
<< "|d| = " << std::norm(d) << '\n';
}
答案 3 :(得分:0)
为什么不直接使用函数重载?
double myNorm(double);
double myNorm(std::complex<double>);
double myNorm(double x) {
return x * x;
}
double myNorm(std::complex<double> x) {
return std::norm(x);
}
您可以将实现放在头文件中的.cpp或(内联时)。