I would like to know how data structures are managed in Eigen.
To be more exact, I would like to know if I should pass them as pointers, or perhaps they actually use some smart pointers.
For example, would the following function make sense:
SparseVector<double> retVector()
{
SparseVector<Double> vec(3);
return vec;
}
or would it be problematic because vec is a local variable, and SparseVector is not just a smart pointer wrapper class around vec?
Meaning, perhaps it is better to use:
SparseVector<double>* retVector()
{
SparseVector<Double> *vec = new SparseVector<double>(3);
return vec;
}
It's more complicated than that. If we were talking about any object, @Anycorn is correct in that the unoptimized version will make a deep copy of object in the function upon return. However, with optimizations enabled copy elision allows the compiler to construct the returned object in place. This is not specific to Eigen. As an example, we can look at a function similar to yours that returns an Eigen object.
Run in Debug (optimizations turned off) we get:
We see that none of the addresses are identical, as would be expected by a naive interpretation of the code. If optimizations are turned on, the picture is a little different:
We see that in case (2) and the sparse matrix example, the addresses of the objects are identical, indicating that the object was created in the target objects address. Note that this is different than move semantics, which require a written move constructor (I'm pretty sure Eigen does not yet have an implemented one).
Regarding Eigen, due to its lazy evaluation, some expressions are not evaluated immediately, but rather when deemed prudent/necessary. This is is not the case in the simple example, but can be if the example had some calculations in it. In such a case, the returned object might be an expression tree that is appended/evaluated in the resulting object.