Инвертировать Eigen :: VectorXd и присвоить другому Eigen :: VectorXd - PullRequest
0 голосов
/ 29 мая 2020

поэтому я наткнулся на эту проблему компиляции с Eigen. Я использую Eigen 3.3.4 и компилирую Linux с g cc 8.4.0. В основном у меня есть определенный класс, наследующий от Eigen::VectorXd, который выглядит так

class dVector : public Eigen::VectorXd {
   public:
    dVector() : Eigen::VectorXd() { setZero(); }
    dVector(int n) : Eigen::VectorXd(n) { setZero(); }
    dVector(const Eigen::VectorXd& v) : Eigen::VectorXd(v) {}
    dVector(const dVector& v) : Eigen::VectorXd(v) {}
    dVector& operator=(const Eigen::VectorXd& v) {
        Eigen::VectorXd::operator=(v);
        return *this;
    }
    dVector& operator=(const dVector& v) {
        Eigen::VectorXd::operator=(v);
        return *this;
    }
   ...
};

И затем в моем коде я использую его так:

static dVector a(100);
// do something with a
dVector b = -a; // <--- won't compile
dVector b = dVector(-a); <---- compiles

Вторая последняя строка не ' t, давая обычное сообщение об ошибке Eigen:

error: no viable conversion from 'const Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>::NegativeReturnType'
 (aka 'const CwiseUnaryOp<scalar_opposite_op<double>,
 const Eigen::Matrix<double, -1, 1, 0, -1, 1> >') to 'dVector'

Теперь я действительно заинтригован, потому что он не компилируется на Linux, а компилируется на Windows, используя MSV C.

Я действительно не понимаю, почему это не компилируется, я подозреваю, что это как-то связано с неявными преобразованиями или с тем, что на самом деле возвращает операция -a; возможно, это не dVector, а дерево операций. Еще не совсем понял, что происходит за кулисами в Eigen.

Итак, два вопроса:

  1. Почему dVector b = -a; не компилируется?

  2. Что еще делает компилятор MSV C, позволяя ему принимать то, что g cc отказывает?

1 Ответ

2 голосов
/ 29 мая 2020

operator-(dVector) не существует, но Eigen::VectorXd является publi c базой dVector, и поэтому Eigen::operator-(Eigen::VectorXd) выбирается для -a.

Этот оператор не возвращает Eigen::VectorXd, но тип оболочки, конвертируемый в Eigen::VectorXd. Этот тип оболочки не может быть преобразован в dVector, так как его необходимо сначала преобразовать в Eigen::VectorXd.

Если вы попробуете dVector b = Eigen::VectorXd(-a), он будет работать по той же причине, что и dVector b = dVector(-a).

Решение: Я бы не рекомендовал публично наследовать от Eigen::VectorXd, вместо этого используйте композицию.

Решение2: Реализуйте operator-(dVector). Теперь компилятор выберет этот оператор вместо этого.

Решение3: Реализовать operator=(Eigen::VectorXd). Тип возвращаемого значения Eigen::operator-(Eigen::VectorXd) может быть преобразован в Eigen::VectorXd и, следовательно, может быть присвоен dVector.

MSV C либо содержит ошибку, либо расширение языка для компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...