I've got a struct that contains a pointer to a second struct, and I'm trying to use a unaryExpr to return the pointer. But it keeps removing the pointer and giving an error about mixed numeric types.
Reproducible example:
#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_; });
}
The problem lies in the way Eigen defines 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
//...
where the remove_all
removes the pointer of the type. I will check if changing this breaks anything else, but putting pointers into matrices is not really what they are designed for.
You can workaround the issue by wrapping your pointer into a trivial pointer-wrapper:
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;}
};
and replacing every s1*
by Ptr<s1>
: https://godbolt.org/z/b_EtDw