idea 1: write one function with DenseBase parameter
signature: template <Derived> void foo(DenseBase<Derived> param)
within function body: param.derived().array()

idea 2: write two functions, one with ArrayBase parameter, the other with MatrixBase parameter
function A signature: template <Derived> void foo(ArrayBase<Derived> param)
within function A body: no need of creating an ArrayWrapper
function B signature: template <Derived> void foo(MatrixBase<Derived> param)
within function B body: param.array()

These are my two ideas for writing a function that applies coefficient-wise math operations and works for ArrayBase as well as MatrixBase.What do you think is the better one? Is there another best practice?

-------------------

1

There are 1 best solutions below

2
davidhigh On

The problem with the first approach is that the ArrayBase class doesn't offer an .array() method, so you need some kind of distinction here. Since C++17, however, you can do that in one function using if constexpr.

This, you can write one function with a DenseBase parameter, and treat the two cases differently. You can introduce another lambda in order to avoid code duplication:

template<typename Derived>
auto cwise_transform(DenseBase<Derived> const& dense)
{
    auto trans = [](auto const& m) { return m.abs(); };  //abs as example

    if constexpr(std::is_base_of_v<MatrixBase<Derived>, Derived>)
    {
          return trans(dense.array());
    }
    else
    {
          return trans(dense);        
    }
}