为什么矩阵在通过 Ref 和 Eigen 时会被复制

Why matrices get copied while passing through Ref & in Eigen

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

A Ref 和 A MatrixXf 仍然是不同的对象,并且将位于不同的地址。这并不意味着复制了整个矩阵:只是创建了一个 Ref 对象。

I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?

不,Ref 不是参考。至少从语言的角度来看不是。 Ref 是一个恰好在 Eigen 中使用的对象,就像 C++ 引用一样。当您传递 const Ref<const T> 时,您正在制作(通过转换创建)Ref 对象的副本,因为您仍在按值 传递 ,但希望您没有复制相应的 T(这就是重点)。当您传递 const Ref<const T>& 时,您没有制作任何副本,因为您通过引用 .

现在,一种方法是否优于另一种方法在很大程度上取决于 Ref 到底是什么,我对此知之甚少,无法做出除 "it's probably small" 之外的任何假设。因为这就是重点:一般意义上的引用,无论是指针、C++ 引用还是 Ref 对象,都应该是非常轻量级的,复制起来容易且快速,这样你就不会当您想在另一个函数中访问它时,必须复制整个引用对象。

最后,您在 const Ref<const T>const Ref<const T>& 之间选择什么可能并不重要,尤其是因为您很可能没有要传递的预先存在的 Ref 对象周围(因此无论如何都会在这两种情况下创建)。但是,选择 const Ref<const T>& 并没有什么坏处。并与 C++ 中通常传递对象的方式保持一致。

Worth a read.