Eigen::Matrixbase protected destructor

  c++, c++17, eigen

I have this class:

template <typename T>
using VecBase = Eigen::MatrixBase<T>;
using spMat = Eigen::SparseMatrix<double>;

template <int Rows>
using Vec = Eigen::Matrix<double, Rows, 1>;


template <typename V>
struct objective_QP 
{
private:
    const spMat Q;
    const Eigen::VectorXd c;

public:

    objective_QP(const spMat Q_, const VecBase<V>& c_): Q(Q_), c(c_)
    {}


    inline double operator()(const VecBase<V> &x)
    {
        return (.5 * x.transpose() * Q * x + c.transpose() * x).value();
    }

    inline VecBase<V> Eval_grad(const VecBase<V> &x)
    {
        return Q.transpose() * x + c;
    }

};

When I try to evaluate the gradient I get protected desctructor-issues:

#include "Eigen/Dense"
#include "Eigen/Sparse"
int main()
{
    const int Nx = 2;
    spMat Q(2, 2);
    std::vector<Triplet> tList;
    tList.push_back(Triplet(0, 0, 5));
    // tList.push_back(Triplet(0, 1, 10));
    tList.push_back(Triplet(1, 1, 1));
    Q.setFromTriplets(tList.begin(), tList.end());
    Vec<Nx> c{0, 0};

    Vec<Nx> x0{1,2};

    objective_QP f(Q, c);
    Vec<Nx> p = f.Eval_grad(x0);
}


error: ‘Eigen::MatrixBase<Derived>::~MatrixBase() [with Derived = Eigen::Matrix<double, 2, 1>]’ is protected within this context

Vec<Nx> p = -f.Eval_grad(x0);

I’m trying to find a solution that preserves the return-by-value approach instead of assigning by reference. Any ideas of why the vector destructor is called before the evaluation is finished?

Replacing the return value with a dynamic-sized matrix solves the issue:

    inline Eigen::MatrixXd Eval_grad(VecBase<V> &x)

Will this have an impact on performance, or will it be resolved by template deduction further down in the eigen-chain?

Working example:
https://godbolt.org/z/4s8zdb6PP

Source: Windows Questions C++

LEAVE A COMMENT