Функция принимает Eigen :: Tensor - сбой вывода аргумента шаблона - PullRequest
2 голосов
/ 03 апреля 2019

Я пытаюсь написать шаблонную функцию, принимающую Eigen::Tensor в качестве аргумента.Тот же подход, который работает для Eigen::Matrix и т. Д., Здесь не работает.

Eigen рекомендует писать функции, используя общий базовый класс.https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

Минимальный пример для Eigen::Matrix, который компилируется:

#include <Eigen/Dense>

template <typename Derived>
void func(Eigen::MatrixBase<Derived>& a) 
{
    a *= 2;
}

int main()
{
    Eigen::Matrix<int, 2, 2> matrix;
    func(matrix);
}

И минимальный пример для Eigen::Tensor, который не компилируется :

#include <unsupported/Eigen/CXX11/Tensor>

template <typename Derived>
void func(Eigen::TensorBase<Derived>& a)
{
    a *= 2;
}

int main()
{
    Eigen::Tensor<int, 1> tensor;
    func(tensor);
}
$ g++ -std=c++11 -I /usr/include/eigen3 eigen_tensor_func.cpp
eigen_tensor_func.cpp: In function ‘int main()’:
eigen_tensor_func.cpp:12:16: error: no matching function for call to ‘func(Eigen::Tensor<int, 1>&)’
     func(tensor);
                ^
eigen_tensor_func.cpp:4:6: note: candidate: ‘template<class Derived> void func(Eigen::TensorBase<Derived>&)’
 void func(Eigen::TensorBase<Derived>& a)
      ^~~~
eigen_tensor_func.cpp:4:6: note:   template argument deduction/substitution failed:
eigen_tensor_func.cpp:12:16: note:   ‘Eigen::TensorBase<Derived>’ is an ambiguous base class of ‘Eigen::Tensor<int, 1>’
     func(tensor);

1 Ответ

1 голос
/ 03 апреля 2019

Тензорный модуль все еще далек от полной совместимости с функциональностью Eigen / Core (это также подразумевает, что документация по базовой функциональности не обязательно относится к тензорному модулю, конечно).

Первое существенное отличие состоит в том, что TensorBase принимает два аргумента шаблона вместо одного, т. Е. Вам нужно написать TensorBase<Derived, Eigen::WriteAccessors>. Также некоторые функциональные возможности либо вообще не реализованы, либо TensorBase не передает их должным образом. Следующие работы с текущей магистралью (2019-04-03):

template <typename Derived>
void func(Eigen::TensorBase<Derived, Eigen::WriteAccessors>& a)
{
    // a *= 2;  // operator*=(Scalar) not implemented
    // a = 2*a; // operator=(...) not implemented/forwarded
    a *= a;     // ok
    a *= 2*a;   // ok
    a *= 0*a+2; // ok

    // a.derived() = 2*a; // derived() is not public
    static_cast<Derived&>(a) = a*2; // ok
}
...