问题
I write a function that takes two DenseBase
as arguments.
The function uses .derived().array()
to convert both Array
and Matrix
to Array
.
I got tired of writing derived
for many times and use auto.
But auto
leads to strange error. Eigen complains that x2
and y2
don't have same shape.
If I don't want to write .derived().array()
for many times, what can I use?
Eigen is from https://github.com/eigenteam/eigen-git-mirror.git
#include <Eigen/Eigen>
int main() {
Eigen::ArrayXf x(3);
Eigen::ArrayXf y(3);
x << 1, 2, 3;
y << 4, 5, 6;
// x.derived().array() * y.derived().array();
auto x2 = x.derived().array();
auto y2 = y.derived().array();
y2 = x2 * y2;
}
Run time error:
CwiseBinaryOp.h:110: ...
Assertion `aLhs.rows() == aRhs.rows()
&& aLhs.cols() == aRhs.cols()' failed.
回答1:
You can fix the runtime issue with auto x2 = x.array().derived();
, that is: reverse array and derived. But auto
is not desirable here. Here is why. Say you have:
template <typename T> void foo(DenseBase<T> &x);
If T
is an Array<>
then x.array().derived()
is an Array<>
and x2
will be a deep copy of x
. In this case you would like to use auto& x2 = ...
.
If T
is something else, e.g., a Matrix<>
, then auto x2 = x.array().derived();
is perfectly fine, but not auto& x2 = ...
.
So what you really want is something as complicated as:
internal::ref_selector<std::decay<decltype(x.array().derived())>::type>::non_const_type
x2 = x.array().derived();
Not nice :(
A simpler solution is to not bother and create an ArrayWrapper
even for inputs that are already in the array world:
ArrayWrapper<T> x2(x.derived());
Yet another simple solution is to enforce the caller to pass expressions in the array world:
template <typename T> void foo(ArrayBase<T> &x) {
T& x2(x.derived());
...
}
来源:https://stackoverflow.com/questions/53324127/densebase-auto-and-binary-operation-says-arrays-have-different-shape