【问题标题】:Why std::complex is not an arithmetic type?为什么 std::complex 不是算术类型?
【发布时间】:2012-08-19 09:15:37
【问题描述】:

我创建了以下 Matrix 类:

template <typename T>
class Matrix
{
    static_assert(std::is_arithmetic<T>::value,"");

public:
    Matrix(size_t n_rows, size_t n_cols);
    Matrix(size_t n_rows, size_t n_cols, const T& value);

    void fill(const T& value);
    size_t n_rows() const;
    size_t n_cols() const;

    void print(std::ostream& out) const;

    T& operator()(size_t row_index, size_t col_index);
    T operator()(size_t row_index, size_t col_index) const;
    bool operator==(const Matrix<T>& matrix) const;
    bool operator!=(const Matrix<T>& matrix) const;
    Matrix<T>& operator+=(const Matrix<T>& matrix);
    Matrix<T>& operator-=(const Matrix<T>& matrix);
    Matrix<T> operator+(const Matrix<T>& matrix) const;
    Matrix<T> operator-(const Matrix<T>& matrix) const;
    Matrix<T>& operator*=(const T& value);
    Matrix<T>& operator*=(const Matrix<T>& matrix);
    Matrix<T> operator*(const Matrix<T>& matrix) const;

private:
    size_t rows;
    size_t cols;
    std::vector<T> data;
};

我尝试使用 std::complex 的矩阵:

Matrix<std::complex<double>> m1(3,3);

问题是编译失败(static_assert失败):

$ make
g++-mp-4.7 -std=c++11   -c -o testMatrix.o testMatrix.cpp
In file included from testMatrix.cpp:1:0:
Matrix.h: In instantiation of 'class Matrix<std::complex<double> >':
testMatrix.cpp:11:33:   required from here
Matrix.h:12:2: error: static assertion failed: 
make: *** [testMatrix.o] Error 1

为什么 std::complex 不是算术类型?我想启用 unsigned int (N)、int (Z)、double (R)、std::complex (C) 和一些自制类(例如代表 Q 的类)......获得这种行为?

编辑 1:如果我删除 static_assert,该类将正常工作。

Matrix<std::complex<double>> m1(3,3);
m1.fill(std::complex<double>(1.,1.));
cout << m1 << endl;

【问题讨论】:

  • 只是出于好奇:如果您删除 Matrix&lt;std::complex&lt;double&gt; &gt; 的实例,您能否实例化并使用该实例 static_assert
  • @MarcusRiemer 是的。效果很好。

标签: c++ types complex-numbers


【解决方案1】:

is_arithmetic 中的 arithmetic 用词不当。或者更确切地说,它是一个 C++ 名词。它的意思与英语中的意思不同。它只是意味着它是内置数字类型(int、float 等)之一。 std::complex 不是内置的,它是一个类。

你真的需要那个static_assert吗?为什么不让用户尝试使用任何类型呢?如果类型不支持所需的操作,那么运气不好。

【讨论】:

  • 显然static_assert 并不是真正需要的。我用它来“清理”代码,让我的矩阵只用于数学......
  • @R.M.为什么要施加这样的限制?
  • 任何想要将 std::string 矩阵相乘的人都值得得到。
  • @BenjaminLindley:static_assert 的重点是为模板替换失败提供更具可读性和合法性的错误消息,而不是大量的模板实例化。
  • @BenjaminLindley 因为这门课是为数学而设计的。使用 double*、std::string、std::vector、std::exception、... 的矩阵是无意义的。
【解决方案2】:

您可以使用通常不被视为“数字”类型的矩阵来做有趣的事情。矩阵和向量实际上从数字推广到多种“代数环”——基本上,任何定义了常用 + 和 * 操作的对象集。

因此,您可以拥有向量矩阵、其他矩阵、复数等。任何支持加法、减法和乘法运算符的类或基本类型都可以正常工作。 如果你正确定义了操作符,隐式编译炸弹应该能捕捉到大多数滥用行为,比如“matrix<:string>”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 2021-06-16
    • 2017-01-17
    • 1970-01-01
    • 2012-09-30
    • 2022-10-15
    相关资源
    最近更新 更多