Reputation: 668
I tested whether the variables get copied by writing the following pieces of code. This piece of code comes from the official documentation: https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html
void cov(const Ref<const MatrixXf> & x, const Ref<const MatrixXf> & y, Ref<MatrixXf> C)
{
cout << "address of x : " << &x << endl;
cout << "address of C : " << &C << endl;
}
int main(int argc, const char * argv[]) {
MatrixXf m1(3,3);
MatrixXf m2(3,3);
MatrixXf m3(3,3);
m1 << 1,2,3,4,5,6,7,8,9;
m2 << 1,2,3,4,5,6,7,8,9;
m3 << 1,2,3,4,5,6,7,8,9;
cout << "address of m1 : " << &m1 << endl;
cout << "address of m3 : " << &m3 << endl;
cov(m1, m2, m3);
}
The output is as followed.
address of m1 : 0x7ffeefbff4e8
address of m3 : 0x7ffeefbff498
address of x : 0x7ffeefbff370
address of C : 0x7ffeefbff308
The address of x and m1, m3 and C are different (I supposed that they should be the same, since I am passing the variables through reference). Could anyone explain to me why?
Thanks to @Nelfeal's answer. I tried to use debugger to prove this.
The following is the debugging info for the above code. We could see that within m1 and x. The "m_data" shared the same address 0x329f800.
However, could someone please tell me the difference btw the following 2 pieces of code? I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?
void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)
void cov(const Ref<const MatrixXf> &x, const Ref<const MatrixXf> &y, Ref<MatrixXf> C)
Upvotes: 0
Views: 668
Reputation: 13269
A Ref
and a MatrixXf
are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref
object gets created.
I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?
No, a Ref
is not a reference. At least not from the language's perspective. A Ref
is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>
, you are making a copy of (are creating by conversion) the Ref
object because you are still passing by value, but hopefully you are not copying the corresponding T
(that's kind of the point). When you pass a const Ref<const T>&
, you are not making any copy since you are passing by reference.
Now, whether one way is better than the other depends largely on what exactly a Ref
is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref
object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.
In the end, it probably doesn't matter what you choose between const Ref<const T>
and const Ref<const T>&
, especially since you most likely don't have a preexisting Ref
object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&
. and be consistant with how objects are passed around in general in C++.
Upvotes: 5