'Use of deleted function' 复制包含 Eigen::CholmodDecomposition 的自定义 class 对象时出错

'Use of deleted function' error when copying custom class object including Eigen::CholmodDecomposition

我想避免在每次求解稀疏系统时都初始化一个 Eigen::CholmodDecomposition 对象。为此,我创建了一个自定义 class。稀疏求解器使用 class 进行初始化,然后在需要时使用,无需重新初始化。我稍后需要做的一件事是复制这些对象。

当我在 class 定义中包含 (1) Eigen::CholmodDecomposition 和 (2) 复制操作时,出现以下错误。如果我删除其中任何一个(没有副本,或者 class 中没有 Eigen::CholmodDecomposition),则没有错误。

我破坏了什么?为什么这不起作用?我如何使这项工作?

#include <RcppEigen.h>

using namespace std;

class TestClass{
public:
  Eigen::CholmodDecomposition<Eigen::SparseMatrix<double> > solver;

  Eigen::MatrixXd solve(const Eigen::SparseMatrix<double>&,
                        const Eigen::MatrixXd&);
  TestClass(){};
};

Eigen::MatrixXd TestClass::solve(const Eigen::SparseMatrix<double>& A, const Eigen::MatrixXd& b){
  solver.compute(A);
  return solver.solve(b);
}

//[[Rcpp::export]]
Eigen::MatrixXd cholmodsolver(const Eigen::SparseMatrix<double>& A,
                              const Eigen::MatrixXd& b){
  TestClass test;

  TestClass test2 = test;
  return test2.solve(A, b);
}

这给出了错误:

error: use of deleted function ‘TestClass::TestClass(const TestClass&)’
   TestClass test2 = test;
                     ^~~~
note: ‘TestClass::TestClass(const TestClass&)’ is implicitly deleted because the default definition would be ill-formed:
 class TestClass{
       ^~~~~~~~~
error: use of deleted function ‘Eigen::CholmodDecomposition<Eigen::SparseMatrix<double, 0, int> >::CholmodDecomposition(const Eigen::CholmodDecomposition<Eigen::SparseMatrix<double, 0, int> >&)’

       ^~~~~~~~~~~~~~~~~~~~

错误是由于 Eigen::CholmodDecomposition 是一个 class,不能像 std::unique_ptr 一样被复制。这导致 TestClass 的复制构造函数,它有一个 Eigen::CholmodDecomposition 类型的成员,被隐式定义为 deleted.

这遵循 C++11 的规则之一:

C++11 § 12.8,p23:

A defaulted copy/move constructor for a class X is defined as deleted (8.4.3) if X has:
...
a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
...