Re: [eigen] Ref<> Problem |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
Thanks a lot for the examples! That helped alot.But despite all these pitfalls what is the suggested way of storing somekind of reference to a block/matrix inside a class. such that one is able to work with it later on, (as a second requirement maybe it should be copiable...?)
I think thats a common use pattern when using Eigen right?As far as I understand the "temporary" naming in your examples relate to temporaries of a certain Eigen type which holds the result as in 2*M which evaluates into an "expression" which then gets injected into a Ref<> -> The 2*M is evaluated and stored in a "temporary" scalar array : double* data somewhere in an Eigen type where the Ref<> has a reference to this "temporary"
Should I still go with Ref<> ? Or how would you code a class which can have a reference to some matrix of numbers , either a full matrix or a block view
Block is just a reference to some data right and should also be considered as initialized-once variable?
Thanks for the rigorous help! I am experienced C++ programmer, but these things with Eigen are quite hard because we always need to make sure there is no stupid temporary involved which leads to a leak or a non-valid reference..., especially when there are wrapper Objects as Map<> or Ref<> or Block<> i cannot grasp the things all the time....
BR Gabriel :-) On 12/04/2014 12:05 PM, Christoph Hertzberg wrote:
On 04.12.2014 10:41, Gabriel wrote:struct A{ // constructor does not generate a temporary: template<class Derived> A(const Eigen::MatrixBase<Derived> & in) : r(in) {}// initializing r might create a temporary but that is stored in rA & operator=(const A & other) { new (&r) Eigen::Ref<const Eigen::MatrixXd>(other.r); return *this; } Eigen::Ref<const Eigen::MatrixXd> r; }; Is that correct, it seems to work :-)?That works for some parts, but there are still some pitfalls: int main() { Eigen::MatrixXd M = Eigen::MatrixXd::Identity(3,3); A A1(3*M); // creates temporary in A1 { A A2(2*M); // creates temporary in A2 A1 = A2; // temporary in A1 is not destructed! --> LEAK } // temporary in A2 gets destructed, invalid reference in A1! std::cout << A1.r << std::endl; // PROBLEM! }So generally, like C++ references, Ref should be considered as initialize-once variables. And, like in C++, strange things can happen, if the variable by which it got initialized runs out of scope before the reference does.Analogous example with C++ references: struct B{ const double& r; B(const double& r_) : r(r_) {} }; B foo() { double x = 3.0; return B(x); // referenced x value will be invalid as soon as foo() exits } int main() { double y = 1.0; B b1(2*y); // temporary created during construction but gets // out of scope before b is usable B b2 = foo(); // x in foo() is out of scope now std::cout << b1.r << "\n" << b2.r << std::endl; } Christoph
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |