Re: [eigen] Matrix::RowXpr::Nested is a reference...

[ Thread Index | Date Index | More Archives ]

2009/10/1 Hauke Heibel <hauke.heibel@xxxxxxxxxxxxxx>:
> Is that correct as is?

Yes. Check in Core/util/XprHelper.h:

template< blabla > struct ei_nested

  typedef typename ei_meta_if<
    typename ei_meta_if<
      (int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
      || ( int(CostEval) <= int(CostNoEval) ),
      const T&
  >::ret type;

See the const T& above ? That's the solution used when doing
ei_nested<RowXpr> by default.

> In the following case
> Replicated<MatrixXd::RowXpr,2,1>(matrix.row(0))
> it means that it fails since matrix.row(0) returns a temporary to which a
> reference is stored in Replicate.

Yes, this is true.

In most cases this is OK as the temporary is alive long enough.

There are some corner cases where this is NOT OK for example if you
want to write a function that returns such a Replicate object.

For these corner cases, we have .nestByValue() which allows you to
force that the row() object is nested by value.

Now I don't remember for sure the exact reasons why we nest by
reference by default, as indeed these are lightweight objects. I think
that was just to avoid useless copying of objects which we feared
would confuse the compiler. It's crucial that the compiler understands
that it can inline all these objects and not actually construct them
in memory.

So it's that's only that, then, feel free with replacing const T& by T
here and checking if the compiler still generates good code. If yes,
then that sounds like great news, as we would then be able to get rid
of NestByValue.


> I used this piece of code to verify my assumption:
> #include "Eigen/Core"
> #include "boost/type_traits/is_reference.hpp"
> void main()
> {
>   typedef Eigen::MatrixXd::RowXpr::Nested type;
>   std::cout << typeid(type).name();
>   if (boost::is_reference<type>::type::value == true) std::cout << "&";
>   std::cout << std::endl;
> }
> Cheers,
> Hauke

Mail converted by MHonArc 2.6.19+