Eigen: возвращая указатель с unaryExpr - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть структура, которая содержит указатель на вторую структуру, и я пытаюсь использовать unaryExpr для возврата указателя. Но он продолжает удалять указатель и выдает ошибку о смешанных числовых типах.

Воспроизводимый пример:

#include <Eigen/Core>

struct s1 {
    double d_;
};

struct s2 {
    s1* struc_;
};

int main() {
    s1 a;
    a.d_ = 1.0;

    s2 a_ptr;
    a_ptr.struc_ = &a;

    Eigen::Matrix<s2,1,1> in(1,1);
    in(0,0) = a_ptr;
    Eigen::Matrix<s1*,1,1> out(1,1);

    //Compiles
    out(0,0) = in(0,0).struc_;

    //Doesn't compile
    out = in.unaryExpr([](s2 x) { return x.struc_; });
}

Также здесь, в проводнике компилятора

1 Ответ

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

Проблема заключается в том, как Эйген определяет result_of:

#if EIGEN_HAS_STD_RESULT_OF
template<typename T> struct result_of {
  typedef typename std::result_of<T>::type type1;
  typedef typename remove_all<type1>::type type;
};
#else
//...

, где remove_all удаляет указатель типа.Я проверю, не нарушает ли это что-то еще, но на самом деле размещение указателей в матрицах - это не то, для чего они предназначены.

Чтобы обойти проблему, можно обернуть указатель в тривиальную обертку-указатель:

template<class X> 
struct Ptr {
    X* ptr;
    operator X*() const {return ptr;}
    X& operator*() const {return *ptr;}
    X* operator->() const {return ptr;}
    Ptr(X* p = 0) : ptr(p) {}
    Ptr& operator=(X* p) {ptr = p; return *this;}
};

и заменить каждый s1* на Ptr<s1>: https://godbolt.org/z/b_EtDw

...