Почему я не могу наследовать от Eigen :: Matrix? - PullRequest
0 голосов
/ 30 октября 2019

У меня этот класс:

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:\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)

Похоже, что компилятор пытается создать неуместные методы (например, пытается позже ошибкадля создания w() для 3-вектора). Что я делаю неправильно? (Почему это не проблема при использовании Eigen::Matrix напрямую?)

Здесь - это живая демонстрация.

1 Ответ

0 голосов
/ 01 ноября 2019

Проблема в том, что 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.

...