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> >&)’
^~~~~~~~~~~~~~~~~~~~
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,
...