Correct usage of the Eigen::Ref<> class
Asked Answered
M

1

50

Eigen has introduced the Ref<> class to write functions with Eigen objects as parameters without the use unnecessary temporaries, when writing template functions is not wanted. One can read about this here.

When searching the internet further, I found several different declarations of parameters using the Ref<> class. In the Eigen documentation they use const Eigen::Ref<const Eigen::MatrixXf>& for a read-only parameter in the first example. In the second example Eigen::Ref<Eigen::MatrixXd> is introduced for read-and-write parameters, BUT here const Eigen::Ref<const Eigen::MatrixXd> is used for read-only parameters (no reference). So my question is:

What is the difference between the following declarations and when do I use which?`

  1. const Eigen::Ref<const Eigen::MatrixXd>&
  2. const Eigen::Ref<const Eigen::MatrixXd>
  3. const Eigen::Ref<Eigen::MatrixXd>&
  4. const Eigen::Ref<Eigen::MatrixXd>
  5. Eigen::Ref<const Eigen::MatrixXd>&
  6. Eigen::Ref<const Eigen::MatrixXd>
  7. Eigen::Ref<Eigen::MatrixXd>&
  8. Eigen::Ref<Eigen::MatrixXd>

For completeness I listed every possible combination of const usage and the reference.

Millburn answered 15/1, 2014 at 8:36 Comment(1)
Personally, I would use const Eigen::Ref<const Eigen::MatrixXd> for read-only parameters and Eigen::Ref<Eigen::MatrixXd> for read-and-write parameters. But I'm not sure about the reference (&).Millburn
P
53

In general, using a non const reference like Ref<T>& is never a good idea because this will only work if the caller already has a Ref<T> object at hand. This discards 5 and 7.

The cases 3 and 4 does not make sense, and they won't compile in general.

Then, there is not much difference between a const Ref<const T> and a const Ref<const T>& because it is unlikely that the function is called with an existing Ref<const T> object, and so a Ref<const T> will have to be created in most cases anyway. Nevertheless, we could still recommend 1 over 2 or 6.

So in summary, we could recommend Ref<T> for a writable reference, and const Ref<const T>& for a const reference.

The option 6, Ref<const T>, might still be interesting if you want to change the matrix that is referenced (not its content) through a call to Ref constructor using placement new.

Pomander answered 15/1, 2014 at 13:10 Comment(7)
would you be able to elaborate on why you would recommend const Ref<const T>& (with &) over const Ref<const T> (no &)? It'd seem that not having the & it'd involve a copy of the Ref object (which I suppose is cheap). In the non-const case the Ref object is getting copied anyway right? there then a difference in performance when passing a Ref& vs. a Ref?Presser
This is because if T is a fixed-size statically allocated type like Matrix4d then then Ref<const T> has to store a Matrix4d as attribute just in case the passed object is not compatible. Therefore, unlike Ref<T> which is always cheap, Ref<const T> might be heavier.Pomander
Is there a way to be warn if a temporary will be created for the const case, or to have a compilation error?Bauer
@janou195, see bug 912Pomander
@ggael, I think that I mixed up two things, the creation of a temporary and the cost of the Ref<const T> creation, but I am still confused with these two. I am sorry, but I don't get with bug 912 in which cases a temporary is created... Furthermore, I also don't get in which cases the creation of a Ref<const T> is cheap or not... What do you mean by "the passed object is not compatible"? Could you please specify in which cases this is cheap or not? And in the "not cheap" cases, what is the cost? Many thanks for helping!Bauer
Does these recommendations change if used for return values instead of parameters?Xenomorphic
@Pomander Because in the case of a return value returning a reference to a Ref means that it cannot be a temporary (which is kind of its main selling point), probably using 2 over 1 as general usage and consistent feels better. What do you think?Truncate

© 2022 - 2024 — McMap. All rights reserved.