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.