Function that accepts both Eigen Dense and Sparse Matrices
If you want to pass EigenBase<Derived>
, you can extract the underlying type using .derived()
(essentially, this just casts to Derived const&
):
template <class Derived>
eigen_return_t<Derived> add(const Eigen::EigenBase<Derived>& A_) {
Derived const& A = A_.derived();
return A + A;
}
More advanced, for this particular example, since you are using A
twice, you can express that using the internal evaluator structure:
template <class Derived>
eigen_return_t<Derived> add2(const Eigen::EigenBase<Derived>& A_) {
// A is used twice:
typedef typename Eigen::internal::nested_eval<Derived,2>::type NestedA;
NestedA A (A_.derived());
return A + A;
}
This has the advantage that when passing a product as A_
it won't get evaluated twice when evaluating A+A
, but if A_
is something like a Block<...>
it will not get copied unnecessarily. However, using internal
functionality is not really recommended (the API of that could change at any time).
The problem of your compiler is the following:
couldn't deduce template parameter 'Derived'
Passing the required type for Derived
should probably work, like follows:
add<double>(v * v)
However I'm not sure because Eigen::Matrix
is not the same type as Eigen::MatrixBase
as it appears to me.
However, if you restrict the compiler less on the type, it will be able to figure out the type:
template <typename T>
auto add(const T& A) {
return A + A;
}
Edit:
Just saw in the comments that this solution has already been posted and that the Eigen documentation recommends to not use auto
. I am not familiar with Eigen, but as it appears to me from skimming over the documentation, it could be that Eigen produces results which represent expressions - e.g. an object representing the matrix addition as an algorithm; not the matrix addition result itself. In this case, if you know that A + A
results in type T
(which it actually should for operator+
in my opinion) you could write it like follows:
template <typename T>
T add(const T& A) {
return A + A;
}
In the matrix example, this should force a matrix result to be returned; not the object representing the expression. However, since you have been originally using eigen_result_t
, I'm not 100% sure.