Ссылка на собственные матрицы

Я ожидал, что когда я создам собственную матрицу и приравняю ее к другой матрице, я увижу эталонную семантику. В частности, я ожидал результата этого

#include <iostream>
#include "Eigen/Dense"

using Eigen::MatrixXd;
using Eigen::VectorXd;

int main() {

    MatrixXd A = MatrixXd::Identity(1, 2);
    MatrixXd B = A;
    A(0, 0) = 4;
    std::cout << "A: " << A << std::endl;
    std::cout << "B: " << B << std::endl;
    return 0;
}

to be

A: 4 0
B: 4 0

но я на самом деле получаю

A: 4 0
B: 1 0

Итак, я предполагаю, что Eigen использует семантику копирования для этих конструкторов. Но если я явно ссылаюсь на ввод (например, в конструкторе класса), я все равно получаю семантику копирования. В частности, вывод

#include <iostream>
#include "Eigen/Dense"

using Eigen::MatrixXd;
using Eigen::VectorXd;

class Holder {

public:
    MatrixXd mat;

    Holder(MatrixXd &A) : mat(A) {
    }
};

int main() {

    MatrixXd A = MatrixXd::Identity(1, 2);
    Holder C(A);
    A(0, 0) = 4;
    std::cout << "A: " << A << std::endl;
    std::cout << "C: " << C.mat << std::endl;
    return 0;
}

is

A: 4 0
C: 1 0

Итак, вопрос... почему кажется, что Эйген копирует матрицы, а не ссылается на них?

Кроме того, в конце концов я хотел бы определить одну матрицу (например, A в приведенном выше примере), а затем создать множество экземпляров класса Holder, где каждый экземпляр имеет ссылку на одну и ту же матрицу. В частности, я хочу, чтобы изменение A приводило к изменению матриц в классах Holder. Загвоздка в том, что я не могу модифицировать сам класс Holder. Так, например, я не мог изменить класс Holder, чтобы сохранить указатель на A вместо самого A. Как бы я это сделал?

Я просмотрел документы Eigen, но не могу найти объяснения.


person bremen_matt    schedule 31.01.2018    source источник


Ответы (1)


Eigen копирует, потому что вы просите его копировать. Если вы хотите иметь ссылку на матрицу, вы должны указать ее, используя правильный синтаксис. В C++ ссылочные переменные указываются с помощью символа &:

MatrixXd A = MatrixXd::Identity(1, 2); // this is an object
MatrixXd& B = A; // this is a reference to an object (notice the &)
person amc176    schedule 31.01.2018