我通过编写以下代码段来测试是否复制了变量。这段代码来自官方文档: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);
}
输出如下。
address of m1 : 0x7ffeefbff4e8
address of m3 : 0x7ffeefbff498
address of x : 0x7ffeefbff370
address of C : 0x7ffeefbff308
x和m1,m3和C的地址不同(我认为它们应该是相同的,因为我正在通过引用传递变量)。谁能向我解释为什么?
感谢@Nelfeal的回答。我试图使用调试器来证明这一点。 以下是上述代码的调试信息。我们可以看到在m1和x内。 “ m_data”共享相同的地址0x329f800。
但是,有人可以告诉我以下两段代码之间的区别吗?我以为“ Ref”本身已经是参考,那么为什么还要添加参考标记“&”呢?
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)
答案 0 :(得分:3)
Ref
和MatrixXf
仍然是不同的对象,并且将位于不同的地址。这并不意味着复制整个矩阵:仅创建一个Ref
对象。
我以为“ Ref”本身就是一个引用,那么为什么我们还必须添加引用标记“&”?
否,Ref
不是参考。至少不是从语言的角度来看。 Ref
是恰好在Eigen中使用的对象,就像C ++引用一样。传递const Ref<const T>
时,您正在复制Ref
对象(通过转换创建),因为您仍然按值传递 ,但希望您不复制相应的T
(这就是重点)。传递const Ref<const T>&
时,由于要通过引用传递 。因此您不会进行任何复制。
现在,一种方法是否优于另一种方法在很大程度上取决于Ref
的确切含义,而我对此一无所知,只能做出“可能很小”的假设。因为这就是要点:一般意义上的引用,无论是指针,C ++引用还是Ref
对象,都应该是非常轻量级,易于复制且快速复制的,因此您不必要在另一个函数中访问它时,必须复制整个引用的对象。
最后,在const Ref<const T>
和const Ref<const T>&
之间进行选择可能无关紧要,尤其是因为您很可能没有预先存在的Ref
对象可以通过(因此无论如何在两种情况下都将创建它)。但是,const Ref<const T>&
并没有什么坏处。并与对象在C ++中的传递方式一致。