1

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.

yar
  • 1,855
  • 13
  • 26
  • *"From my point of view this is not expected behaviour."* As [this link](https://stackoverflow.com/questions/16570661/reference-a-temporary-in-msvc) explains, GCC is correct to reject the code. *"Is there an elegant fix"* I don't know much about Eigen, but can't you simply do `auto a_block = ...;`? – HolyBlackCat Mar 17 '19 at 12:14
  • right, `auto a_block = ...;` should solve the problem! Thanks a lot! – yar Mar 17 '19 at 12:18
  • Or you can use an lvalue `auto&&` reference, or `Eigen::Ref`. – chtz Mar 17 '19 at 17:41

1 Answers1

6

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.

hegel5000
  • 876
  • 1
  • 7
  • 13