【问题标题】:Why matrices get copied while passing through Ref & in Eigen为什么矩阵在通过 Eigen 中的 Ref & 时被复制
【发布时间】:2019-04-14 10:08:36
【问题描述】:

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

【问题讨论】:

    标签: c++ eigen eigen3


    【解决方案1】:

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

    我以为“Ref”本身已经是一个引用,那为什么还要加上引用标记“&”呢?

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

    现在,一种方法是否比另一种更好在很大程度上取决于 Ref 到底是什么,我对此知之甚少,无法做出任何假设,除了“它可能很小”。因为这就是重点:一般意义上的引用,无论是指针、C++ 引用还是Ref 对象,都应该是非常轻量级、易于复制且快速复制的,因此您不必当你想在另一个函数中访问它时,复制整个引用的对象。

    最后,您在 const Ref&lt;const T&gt; 和 const Ref&lt;const T&gt;&amp; 之间选择什么可能并不重要,特别是因为您很可能没有预先存在的 Ref 对象来传递(所以它将被创建无论如何,在这两种情况下)。但是,选择const Ref&lt;const T&gt;&amp; 并没有什么坏处。并且与 C++ 中对象的一般传递方式保持一致。

    Worth a read.

    【讨论】:

    • 感谢 Nelfeal!在您的回答启发后,我编辑了我的问题。但是你知道我们为什么要加上“&”,因为 Ref 本身就是一个引用吗?
    • @JackieLam 已编辑。
    • 再次感谢您的详尽回答!现在我想我完全理解了。
    • Ref&lt;const T&gt; 包含一个临时对象(只有在传递的对象实际上不能仅通过指针传递的情况下才使用它),这就是为什么它通常应该通过引用传递。跨度>
    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    相关资源
    最近更新 更多