问题
I have a class A
templated with a Scalar
which can be real- or complex-valued. It has a method realPart
which is supposed to return the real part of the number. If Scalar
is real-valued, it should just return the original Scalar, and .real()
if it's of complex type.
When writing
#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
}
the compiler will complain at z1.realPart()
because double
doesn't know .real()
.
How can I guard .real()
at compile time?
回答1:
This can be done with a simple is_complex
trait and 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_;
};
来源:https://stackoverflow.com/questions/30736951/templated-class-check-if-complex-at-compile-time