Hi!
On 03/10/2019 06.45, Dale Lukas Peterson wrote:
> Following the guidance here [0], I have:
> 
> template <typename Derived>
> void test(const Eigen::MatrixBase<Derived>& a)
> {
>    // Use case 1:
>    Derived aa;
>    // do stuff with aa
> 
>    // Use case 2:
>    Derived bb = a;
>    // do stuff with bb
> }
> 
> If I create an Eigen::Matrix and call test like so, it works fine:
> 
> Eigen::Matrix<double, 2, 4> A;
> A << 1, 2, 3, 4,
>          5, 6, 7, 8;
> // Works
> test(A);
This works, because `Derived = Matrix<double, 2, 4>` in this case, which 
is a valid standalone object.
> 
> However, the following doesn't work:
> test(A.block<2, 1>(0, 1));
In this case `Derived` is something like `Block<Matrix<double,2,4>,2,1>` 
which is not usable as a stand-alone object. It can only be constructed 
from an existing Matrix object where it points to.
> 
> However, the following does work:
> test(A.block<2, 1>(0, 1).eval());
The result of `.eval()` is again a `Matrix` object (should be 
`Matrix<double,2,1>`).
> 
> Is .eval() the right approach here? Should I being doing something else at
> the call site, or in my function definition to better handle this? Does the
> return value of `.block<2, 1>(0, 1)` constitute a "plain matrix or vector
> (not an _expression_)" [1] or not, so that I can be certain this isn't
> creating a useless copy?
`.block<..>(..)` will always return a "free" view into an existing 
object (or actually a block of another _expression_), `anything.eval()` 
will always return a `Matrix<...>` (or `Array<...>` object) which will 
be a copy, unless `anything` already was a plain Matrix or Array (in 
that case it will return a const reference).
If you want to have a modifiable plain matrix object inside `void 
test(...)` with the same size as `MatrixBase<Derived>`, you can write
   typedef typename Derived::PlainObject Mat;
   Mat aa;
I ended up doing this as:
Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime> aa;
However I like your solution better since it is shorter and presumably it also captures the Options, MaxRows, and MaxCols template parameters correctly from Derived, whereas what I did will use whatever the defaults are configured to be.
Thanks again,
Luke
 
Usage demo: https://godbolt.org/z/hgaEra
Cheers,
Christoph
> 
> Sincerely,
> Luke
> 
> [0] https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
> [1] https://eigen.tuxfamily..org/dox/classEigen_1_1DenseBase.html#title39
> 
-- 
  Dr.-Ing. Christoph Hertzberg
  Besuchsadresse der Nebengeschäftsstelle:
  DFKI GmbH
  Robotics Innovation Center
  Robert-Hooke-Straße 5
  28359 Bremen, Germany
  Postadresse der Hauptgeschäftsstelle Standort Bremen:
  DFKI GmbH
  Robotics Innovation Center
  Robert-Hooke-Straße 1
  28359 Bremen, Germany
  Tel.:     +49 421 178 45-4021
  Zentrale: +49 421 178 45-0
  E-Mail:   christoph.hertzberg@xxxxxxx
  Weitere Informationen: http://www.dfki.de/robotik
   -------------------------------------------------------------
   Deutsches Forschungszentrum für Künstliche Intelligenz GmbH
   Trippstadter Strasse 122, D-67663 Kaiserslautern, Germany
   Geschäftsführung:
   Prof. Dr. Jana Koehler (Vorsitzende)
   Dr. Walter Olthoff
   Vorsitzender des Aufsichtsrats:
   Prof. Dr. h.c. Hans A. Aukes
   Amtsgericht Kaiserslautern, HRB 2313
   -------------------------------------------------------------
For a successful technology, reality must take precedence over public relations, for Nature cannot be fooled. -- Richard Feynman