为什么我不能从 Eigen::Matrix 继承?
Why can't I inherit from Eigen::Matrix?
我有 this class:
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) 上,我得到 really strange errors:
c:\include\eigen3\eigen\src\core\densebase.h(482): error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS (compiling source file c:\code\my_point.cxx) [C:\workspace\KwiverWindows\build\vital\vital.vcxproj]
c:\include\eigen3\eigen\src\core\densebase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\matrixbase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\plainobjectbase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\matrix.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:\code\my_point.cxx)
看起来编译器正在尝试实例化不适当的方法(例如,稍后的错误是尝试为 3 向量实例化 w()
)。我究竟做错了什么? (为什么直接使用Eigen::Matrix
没有问题?)
Here 是现场演示。
问题是 Eigen 不使用 SFINAE/enable_if
来隐藏 "inappropriate" 成员,它只是依赖于它们从未被实例化(如果有人试图使用它们,则使用静态断言)。因此,Eigen
class——至少,Eigen::Matrix
——无法显式实例化。
这可以通过一个简单的例子看出:
#include <Eigen/Core>
template class Eigen::Matrix< double, 3, 1 >;
真正的谜团是为什么 GCC 允许显式实例化 classes derived from Eigen::Matrix
。 MSVC 没有,但似乎 MSVC 可能是正确的,这里。
短期解决方案是不导出 my_point
。当然,这需要 my_point
的所有方法的定义在 header 中可见,或者单独导出(而不是尝试导出整个 class)。
长期解决方案是修复 Eigen,以便可以显式实例化其类型:https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1768.
我有 this class:
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) 上,我得到 really strange errors:
c:\include\eigen3\eigen\src\core\densebase.h(482): error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS (compiling source file c:\code\my_point.cxx) [C:\workspace\KwiverWindows\build\vital\vital.vcxproj]
c:\include\eigen3\eigen\src\core\densebase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\matrixbase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\plainobjectbase.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:\code\my_point.cxx)
c:\include\eigen3\eigen\src\core\matrix.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:\code\my_point.cxx)
看起来编译器正在尝试实例化不适当的方法(例如,稍后的错误是尝试为 3 向量实例化 w()
)。我究竟做错了什么? (为什么直接使用Eigen::Matrix
没有问题?)
Here 是现场演示。
问题是 Eigen 不使用 SFINAE/enable_if
来隐藏 "inappropriate" 成员,它只是依赖于它们从未被实例化(如果有人试图使用它们,则使用静态断言)。因此,Eigen
class——至少,Eigen::Matrix
——无法显式实例化。
这可以通过一个简单的例子看出:
#include <Eigen/Core>
template class Eigen::Matrix< double, 3, 1 >;
真正的谜团是为什么 GCC 允许显式实例化 classes derived from Eigen::Matrix
。 MSVC 没有,但似乎 MSVC 可能是正确的,这里。
短期解决方案是不导出 my_point
。当然,这需要 my_point
的所有方法的定义在 header 中可见,或者单独导出(而不是尝试导出整个 class)。
长期解决方案是修复 Eigen,以便可以显式实例化其类型:https://eigen.tuxfamily.org/bz/show_bug.cgi?id=1768.