模板化类:检查编译时是否复杂

时间:2015-06-09 15:49:55

标签: c++ templates complex-numbers

我有一个用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()

1 个答案:

答案 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_;
};