Search code examples
c++eigenrcpp

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


I want to avoid inizializing an Eigen::CholmodDecomposition object each time I want to solve a sparse system. To do so, I have created a custom class. The sparse solver gets initialized with the class and then used whenever necessary, without requiring re-initialization. One thing I need to do later is a copy of such objects.

When I include both (1) Eigen::CholmodDecomposition in the class definition and (2) a copy operation, I get the errors below. If I remove either (either no copy, or no Eigen::CholmodDecomposition in the class) there is no error.

What am I breaking? Why is this not working? How do I make this work?

#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);
}

This gives the errors:

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> >&)’

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

Solution

  • The error is due to Eigen::CholmodDecomposition being a class that cannot be copied just like std::unique_ptr. This causes the copy constructor of TestClass, which has a member of type Eigen::CholmodDecomposition, to be implicitly defined as deleted.

    This follows one of the rules of 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,
    ...