为什么通过Ref&in Eigen时会复制矩阵

时间:2018-11-11 13:53:55

标签: c++ eigen eigen3

我通过编写以下代码段来测试是否复制了变量。这段代码来自官方文档: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。 enter image description here enter image description here

但是,有人可以告诉我以下两段代码之间的区别吗?我以为“ 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)

1 个答案:

答案 0 :(得分:3)

RefMatrixXf仍然是不同的对象,并且将位于不同的地址。这并不意味着复制整个矩阵:仅创建一个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 ++中的传递方式一致。

Worth a read.