Search code examples
c++c++11eigeneigen3

auto reference to Eigen block not behaving as expected


I want to use an auto reference to a block of an eigen matrix:

#include <Eigen/Dense>
using namespace Eigen;
void foo(MatrixXf& a)
{
    auto& a_block = a.block(2, 3, 4, 5);
    a_block = MatrixXf::Random(4,5);
}    

This does not compile with GCC, since a.block(2, 3, 4, 5) is evaluated into a temporary, while a.block(2, 3, 4, 5) = MatrixXf::Random(4,5); works perfectly.

From my point of view this is not expected behaviour. Is there an elegant fix to this problem? Should this be considered a bug / feature request to Eigen?

EDIT:

using auto instead of auto& solves the problem!

The question has been marked as a duplicate of Reference a temporary in msvc, but it has nothing to do with MSVC. I also made clear that it's obvious that a.block(2, 3, 4, 5) is evaluated into a temporary. The question was about whether this is correct behaviour of Eigen.


Solution

  • block doesn't actually return a reference, but instead it creates a reference-like object of type Block. A freshly created rvalue of any type can't be assigned to a non-const lvalue reference, so this is all expected behavior.

    Assigning to a Block rvalue is fine because it has an overloaded operator= (which unfortunately doesn't get its own entry in the documentation page because it looks like they generate the = definition using a macro). That = function then sends all your data to the relevant parts of the Matrix that the Block was created from.