Registered Member
|
Hello. We're big fans of Eigen and use it extensively. The comma initialization feature is very nice, but I'm wondering why implicit conversion from CommaInitializer to XprType is not used to avoid the need for .finished() when using comma initialization as a temporary object?
To test this, I wrote a "special" CommaInitializer class. This seems to work fine, and enables syntax like:
Here is the code for SpecialCommaInitializer:
To test out the above code, the DenseBase<Derived>::operator<< implementations in Core/CommaInitializer.h should me modified to return SpecialCommaInitializer instead of CommaInitializer. I wondered if not allowing the syntax without .finished() was a design decision? P.S. I'd be glad to supply a patch for CommaInitializer that enables this implicit conversion if it makes sense to include this feature. Thanks and best regards, Richard Roberts |
Moderator
|
This seems to be a nice addition. However, the .finished() is still needed to be able to call members or operators. A proper patch with a unit test and updated documentation is very welcome!
|
Moderator
|
hm, actually this trick is quite limited because it also won't work with templated functions. One solution would be to make CommaInitializer inherits MatrixBase. The only drawback is that I don't see how to check the matrix has been completely filled.
|
Registered Member
|
That's a good point - the only reason the trick works for us is that we rarely use templated functions that accept DenseBase, we normally just use VectorXd and MatrixXd. If CommaInitializer was inherited from DenseBase, and we need to know if the matrix is fully initialized, I think it work to check the m_row and m_col members against the size of m_xpr.
Can you think of an easy way to derive CommaInitializer from DenseBase, such that it's not necessary to implement the whole DenseBase interface, and just have some kind of implicit conversion? I tried adding conversion operators to DenseBase<XprType> but this doesn't work. |
Moderator
|
A good example to see how to make CommaInitializer a true expression is the Flagged class (src/Core/Flagged.h). Basically you only have to specialize internal::traits for CommaInitializer and make it inherits traits<XprType>, and in CommaInitializer a few members: rows/cols/coeff*/*packet* that are simply forwarded to the nested matrix object.
|
Registered Member
|
Great, this works for templated functions now. I tested with functions of the form fcn(const DenseBase<Derived>&) and fcn(const MatrixBase<Derived>&). Below is the new code for SpecialCommaInitializer that inherits from MatrixBase. Please let me know if you notice any mistakes.
We will use this in-house here for a little while to try to work out any problems and then I will submit a patch for the real CommaInitializer when I'm relatively certain it doesn't cause any problems.
|
Moderator
|
oh, maybe Flagged was not perfect example since it is for MatrixBase only. To make it work with both Array* and Matrix*, you need and additional trick to decide whether the base class is MatrixBase or ArrayBase. I also added the data() member: (not tested so there might be typos)
|
Registered Member
|
Cool! Is it a typo that the base class is 'internal::dense_xpr_base<XprType>::type' but the Base typedef is 'typename internal::TransposeImpl_base<XprType>::type' ?
|
Moderator
|
oops, copy paste mistake! It must be:
|
Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]