为什么我不能从 Eigen::Matrix 继承?

Why can't I inherit from Eigen::Matrix?

本文关键字:Matrix 继承 Eigen 不能 为什么      更新时间:2023-10-16

我有这个类:

template < unsigned N, typename T >
class MY_EXPORT my_point : protected Eigen::Matrix< T, N, 1 >
{
public:
using vector_type = Eigen::Matrix< T, N, 1 >;
my_point() : vector_type{ vector_type::Zero() } {}
using vector_type::vector_type;
};

我的 Linux (GCC) 版本很好。但是,在Windows(MSVC 15.9.16)上,我收到非常奇怪的错误:

c:includeeigen3eigensrccoredensebase.h(482): error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS (compiling source file c:codemy_point.cxx) [C:workspaceKwiverWindowsbuildvitalvital.vcxproj]
c:includeeigen3eigensrccoredensebase.h(481): note: while compiling class template member function 'const float &Eigen::DenseBase<Derived>::value(void) const'
with
[
Derived=Eigen::Matrix<float,4,1,0,4,1>
] (compiling source file c:codemy_point.cxx)
c:includeeigen3eigensrccorematrixbase.h(50): note: see reference to class template instantiation 'Eigen::DenseBase<Derived>' being compiled
with
[
Derived=Eigen::Matrix<float,4,1,0,4,1>
] (compiling source file c:codemy_point.cxx)
c:includeeigen3eigensrccoreplainobjectbase.h(100): note: see reference to class template instantiation 'Eigen::MatrixBase<Derived>' being compiled
with
[
Derived=Eigen::Matrix<float,4,1,0,4,1>
] (compiling source file c:codemy_point.cxx)
c:includeeigen3eigensrccorematrix.h(180): note: see reference to class template instantiation 'Eigen::PlainObjectBase<Eigen::Matrix<float,4,1,0,4,1>>' being compiled (compiling source file c:codemy_point.cxx)

看起来编译器正在尝试实例化不适当的方法(例如,后来的错误试图实例化 3 向量的w())。我做错了什么?(为什么直接使用Eigen::Matrix时这不是问题?

这是一个现场演示。

问题是 Eigen 不使用 SFINAE/enable_if来隐藏"不合适"的成员,它只是依赖于它们永远不会被实例化(如果有人试图使用它们,则使用静态断言)。因此,Eigen类(至少是Eigen::Matrix类)无法显式实例化。

这可以从一个微不足道的例子中看出:

#include <Eigen/Core>
template class Eigen::Matrix< double, 3, 1 >;

(现场演示)

真正的谜团是为什么GCC允许显式实例化派Eigen::Matrix的类。MSVC没有,但似乎MSVC可能是正确的,在这里。

短期解决方案是不出口my_point.当然,这要求my_point所有方法的定义要么在标头中可见,要么单独导出(而不是尝试导出整个类)。

更长期的解决方案是修复 Eigen,以便可以显式实例化其类型:https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1768。