Templated class: Check if complex at compile time

让人想犯罪 __ 提交于 2019-12-11 03:34:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!