我有一个用A
模板化的课程Scalar
,可以是真值或复值。它有一个方法realPart
,它应该返回数字的实部。如果Scalar
是实值的,它应该只返回原始标量,如果它是复杂类型,则.real()
。
写作时
#include <complex>
#include <iostream>
template<class Scalar>
class A {
public:
A (const Scalar z):
z_(z)
{
}
Scalar realPart()
{
return z_.real();
}
private:
Scalar z_;
};
int main() {
A<std::complex<double>> z0((1.0, 2.0));
std::cout << z0.realPart() << std::endl; // check
A<double> z1(1.0);
std::cout << z1.realPart() << std::endl; // mööp
}
编译器会在z1.realPart()
投诉,因为double
并不知道.real()
。
如何在编译时保护.real()
?
答案 0 :(得分:3)
这可以通过简单的is_complex
特征和SFINAE来完成:
template<class T> struct is_complex : std::false_type {};
template<class T> struct is_complex<std::complex<T>> : std::true_type {};
template<class Scalar>
class A {
public:
A(const Scalar z) : z_(z)
{ }
template<class S = Scalar, std::enable_if_t<is_complex<S>{}>* = nullptr>
Scalar realPart()
{
return z_.real();
}
template<class S = Scalar, std::enable_if_t<!is_complex<S>{}>* = nullptr>
Scalar realPart()
{
return z_;
}
private:
Scalar z_;
};