将一个Eigen::VectorXd反转并分配给另一个Eigen::VectorXd。

问题描述 投票:0回答:1

所以我偶然发现了这个Eigen的编译问题,我使用的是Eigen 3.3.4,在Linux上用gcc 8.4.0编译。我使用Eigen 3.3.4,在Linux上用gcc 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

第二行最后一行没有编译,给出了通常的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上却能用MSVC编译。

我真的不明白为什么这个不能编译,我怀疑这与隐式转换有关,或者说与以下操作有关 -a 实际返回;也许这不是一个 dVector 但一个操作树。还没有完全掌握Eigen背后的情况。

那么就有两个问题。

  1. 为什么 dVector b = -a; 编译?

  2. MSVC编译器做了什么不同的事情,让它可以接受gcc拒绝的任何东西?

c++ gcc visual-c++ eigen
1个回答
2
投票

operator-(dVector) 不存在,但 Eigen::VectorXd 是一个公共基础的 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.

MSVC要么有一个bug,要么有一个语言扩展,使得这个编译。

© www.soinside.com 2019 - 2024. All rights reserved.