反转 Eigen::VectorXd 并分配给另一个 Eigen::VectorXd
Invert a Eigen::VectorXd and assign to another Eigen::VectorXd
所以我偶然发现了 Eigen 的这个编译问题。我正在使用 Eigen 3.3.4 并使用 gcc 8.4.0 在 Linux 上编译。
基本上我有一个定义的 class 继承自 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 上编译,但它使用 MSVC 在 Windows 上编译。
我真的不明白为什么这不能编译,我怀疑它与隐式转换或操作 -a
实际上 returns 有什么关系;也许它不是 dVector
而是操作树。还没有完全掌握 Eigen 幕后发生的事情。
那么两个问题:
为什么dVector b = -a;
编译不了?
MSVC 编译器做了什么不同的事情来允许它接受 gcc 拒绝的任何内容?
operator-(dVector)
不存在,但 Eigen::VectorXd
是 dVector
的 public 基,因此 Eigen::operator-(Eigen::VectorXd)
被选为 -a
。
此运算符不是 return Eigen::VectorXd
而是包装类型可转换
至 Eigen::VectorXd
。此包装器类型不可转换为 dVector
,因为需要先将其转换为 Eigen::VectorXd
。
如果您尝试 dVector b = Eigen::VectorXd(-a)
它会起作用,原因与 dVector b = dVector(-a)
起作用相同。
解决方法:
我不建议 public 从 Eigen::VectorXd
继承,而是使用组合。
方案二:
实施 operator-(dVector)
。现在编译器将选择此运算符。
方案三:
实施 operator=(Eigen::VectorXd)
。 Eigen::operator-(Eigen::VectorXd)
的 return 类型可转换为 Eigen::VectorXd
,因此可以分配给 dVector
。
MSVC 有错误或语言扩展来进行此编译。
所以我偶然发现了 Eigen 的这个编译问题。我正在使用 Eigen 3.3.4 并使用 gcc 8.4.0 在 Linux 上编译。
基本上我有一个定义的 class 继承自 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 上编译,但它使用 MSVC 在 Windows 上编译。
我真的不明白为什么这不能编译,我怀疑它与隐式转换或操作 -a
实际上 returns 有什么关系;也许它不是 dVector
而是操作树。还没有完全掌握 Eigen 幕后发生的事情。
那么两个问题:
为什么
dVector b = -a;
编译不了?MSVC 编译器做了什么不同的事情来允许它接受 gcc 拒绝的任何内容?
operator-(dVector)
不存在,但 Eigen::VectorXd
是 dVector
的 public 基,因此 Eigen::operator-(Eigen::VectorXd)
被选为 -a
。
此运算符不是 return Eigen::VectorXd
而是包装类型可转换
至 Eigen::VectorXd
。此包装器类型不可转换为 dVector
,因为需要先将其转换为 Eigen::VectorXd
。
如果您尝试 dVector b = Eigen::VectorXd(-a)
它会起作用,原因与 dVector b = dVector(-a)
起作用相同。
解决方法:
我不建议 public 从 Eigen::VectorXd
继承,而是使用组合。
方案二:
实施 operator-(dVector)
。现在编译器将选择此运算符。
方案三:
实施 operator=(Eigen::VectorXd)
。 Eigen::operator-(Eigen::VectorXd)
的 return 类型可转换为 Eigen::VectorXd
,因此可以分配给 dVector
。
MSVC 有错误或语言扩展来进行此编译。