Почему матрицы копируются при прохождении через Ref & in Eigen - PullRequest
0 голосов
/ 11 ноября 2018

Я проверил, копируются ли переменные, написав следующие фрагменты кода. Этот кусок кода взят из официальной документации: 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

Однако, может, кто-нибудь подскажет разницу между следующими 2 частями кода? Я предположил, что «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 голосов
/ 11 ноября 2018

A 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 ++.

Стоит прочитать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...