Search code examples
c++c++17eigentemplate-argument-deductionclass-template

Copy templated function argument in Eigen


I am writing a generic class that utilizes Eigen data types. I already have problems assigning constructor arguments to class member variables. A simplified version of my code would be:

template <typename Derived>
class A
{
public:
  Eigen::Matrix<Derived> M; // error C2976: too few template parameters

A(const Eigen::DenseBase<Derived> & V)
{
  M = V.eval(); // I would want to snapshot the value of V.
}
};

My question is now what data type M should be? I tried a variety of options, such as:

Eigen::internal::plain_matrix_type_column_major<Derived> M;
Eigen::DenseBase<Derived> M;

but they just generate different errors. Note that I use C++17 and expect the class template parameter to be inferred from the constructor.


Solution

  • Your container needs the actual "plain type" as template argument:

    template <typename PlainType>
    class A
    {
        PlainType M; 
    public:
        template<class Derived>
        A(const Eigen::MatrixBase<Derived> & V) : M(V) {}
    };
    

    And you need an additional template deduction rule:

    template<class Derived>
    A(const Eigen::MatrixBase<Derived> & V) -> A<typename Derived::PlainObject>;
    

    Usage example (on godbolt):

    template<class X>
    void bar(X&); // just to read full type of A
    
    void foo(Eigen::Matrix2d const& M)
    {
        A a = M*M;
        bar(a);  // calls bar<A<Matrix2d>>();
    }