Eigen:: 无法将 Block<Derived> 转换为 Ref<Derived> 当 cols 数量固定时
Eigen:: cannot convert Block<Derived> to Ref<Derived> when number of cols is fixed
我最近更新到最新的 Eigen 版本 (3.3.90),看起来它破坏了我之前工作的东西(在我使用 libigl 库附带的 Eigen 版本 3.2.10 之前)。
我想将块的结果存储到一个 ref 对象中,该对象将被传递并最终用于更新块被提取的矩阵形式的内部。
一个不再编译的最小示例:
#include <Eigen/Dense>
int main(int argc, char *argv[])
{
typedef Eigen::Matrix<bool, Eigen::Dynamic, 1> Mtype;
typedef Eigen::Block<Mtype> Btype;
typedef Eigen::Ref<Mtype> Rtype;
Mtype m(2, 1);
Btype bm = m.block(0, 0, 1, 1);
Rtype rm = m; // OK
Rtype rbm = bm; // Visual studio 2017 error C2440: 'initialisation' : impossible conversion
}
请注意,const 版本确实有效,我认为这是由于 const 的 Ref 专门化,它重新创建了一个临时副本:
typedef Eigen::Ref<const Mtype> CRtype;
CRtype crbm = bm; // OK
类似地使用具有 行数和列数 Dynamic 的 Matrix 类型,也编译:
typedef Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> Mtype;
typedef Eigen::Block<Mtype> Btype;
typedef Eigen::Ref<Mtype> Rtype;
Mtype m(2, 1);
Btype bm = m.block(0, 0, 1, 1);
Rtype rbm = bm;
有什么线索吗?
非常感谢!
此致,
杰罗姆
Eigen 版本 3.3.90 是一个开发分支,那里的东西可能会被破坏。使用最新的稳定版本 (3.3.7) 可以解决此问题。话虽如此,您可以向 Eigen 开发人员提交错误报告,以确保注意到这一点(尽管到您这样做时,他们可能已经看到了 post)。
我之前的回答下结论太快了。现在已修复:https://bitbucket.org/eigen/eigen/commits/cacb7b4ace39/
尽管如此,还是保留编译时向量为编译时向量比较好。此信息被 Block<VectorXd>
(和 m.block(0, 0, 1, 0)
)丢失,因为它在运行时可能有 1 或 0 列,例如:
Block<VectorXd> bm = m.block(0, 0, 1, 0);
完全没问题。所以在你的情况下,我仍然建议保留这些信息,例如:
auto bm = m.segment(0,1);
auto bm = m.block(0,0,1,fix<1>); // fix is new in Eigen 3.4
auto bm = m.block<Dynamic,1>(0,0,1,1); // <3.4 version of the above cleaner line
这是一个典型的情况,您应该真正使用 auto
。也可以直接初始化Ref,例如:
Ref<MType> rm = m.segment(0,1);
我最近更新到最新的 Eigen 版本 (3.3.90),看起来它破坏了我之前工作的东西(在我使用 libigl 库附带的 Eigen 版本 3.2.10 之前)。
我想将块的结果存储到一个 ref 对象中,该对象将被传递并最终用于更新块被提取的矩阵形式的内部。
一个不再编译的最小示例:
#include <Eigen/Dense>
int main(int argc, char *argv[])
{
typedef Eigen::Matrix<bool, Eigen::Dynamic, 1> Mtype;
typedef Eigen::Block<Mtype> Btype;
typedef Eigen::Ref<Mtype> Rtype;
Mtype m(2, 1);
Btype bm = m.block(0, 0, 1, 1);
Rtype rm = m; // OK
Rtype rbm = bm; // Visual studio 2017 error C2440: 'initialisation' : impossible conversion
}
请注意,const 版本确实有效,我认为这是由于 const 的 Ref 专门化,它重新创建了一个临时副本:
typedef Eigen::Ref<const Mtype> CRtype;
CRtype crbm = bm; // OK
类似地使用具有 行数和列数 Dynamic 的 Matrix 类型,也编译:
typedef Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> Mtype;
typedef Eigen::Block<Mtype> Btype;
typedef Eigen::Ref<Mtype> Rtype;
Mtype m(2, 1);
Btype bm = m.block(0, 0, 1, 1);
Rtype rbm = bm;
有什么线索吗?
非常感谢!
此致,
杰罗姆
Eigen 版本 3.3.90 是一个开发分支,那里的东西可能会被破坏。使用最新的稳定版本 (3.3.7) 可以解决此问题。话虽如此,您可以向 Eigen 开发人员提交错误报告,以确保注意到这一点(尽管到您这样做时,他们可能已经看到了 post)。
我之前的回答下结论太快了。现在已修复:https://bitbucket.org/eigen/eigen/commits/cacb7b4ace39/
尽管如此,还是保留编译时向量为编译时向量比较好。此信息被 Block<VectorXd>
(和 m.block(0, 0, 1, 0)
)丢失,因为它在运行时可能有 1 或 0 列,例如:
Block<VectorXd> bm = m.block(0, 0, 1, 0);
完全没问题。所以在你的情况下,我仍然建议保留这些信息,例如:
auto bm = m.segment(0,1);
auto bm = m.block(0,0,1,fix<1>); // fix is new in Eigen 3.4
auto bm = m.block<Dynamic,1>(0,0,1,1); // <3.4 version of the above cleaner line
这是一个典型的情况,您应该真正使用 auto
。也可以直接初始化Ref,例如:
Ref<MType> rm = m.segment(0,1);