Reputation: 335
I have a matrix that I want to be able to share access to via a struct array containing references to said matrix.
Is there any way to achieve this so I can modify the matrix by pulling from this buffer?
struct something {
vector<vector<double>> &a;
};
something buffer[3];
void modify(something &arr) {
(arr.a)[0][0] = 10;
cout << (arr.a)[0][0] << endl;
}
int main(int argc, const char * argv[]) {
vector<vector<double>> a(5, vector<double>(5));
buffer[0] = {a};
modify(buffer[0]);
// want this to print 10
cout << a[0][0] << endl;
return 0;
}
The problem with this, of course, is that a struct with a reference inside of it does not have a default constructor and thus can't be initialized in this way.
Upvotes: 0
Views: 52
Reputation: 238361
You need to create the matrices first so that you can refer to them. That way you can initialise the references correctly:
vector<vector<double>> matrices[3];
something buffer[]{matrices[0], matrices[1], matrices[2]};
That is not the only problem however. Another is that you attempt to assign something
:
buffer[0] = {a};
This is not allowed because something
is not assignable. It is not assignable because the class contains a reference member.
// want this to print 10
There is no way to make the global reference refer to a local variable.
Given that you are trying to use the class in several ways that are contradictory to having a reference member, perhaps it would be better to re-design it to not use a reference.
This seems like a potentially good use case for a pointer. Unlike references, pointers can be assigned after initialisation. Be very careful however when storing pointers to local objects in the global array. It is very easy to end up with an invalid pointer.
Upvotes: 1
Reputation: 1399
This is a good use case for pointers, as they can be default constructed and you can assign different variables to them, unlike references:
struct something {
vector<vector<double>> *a = nullptr; //pointer variable
};
something buffer[3];
void modify(something &arr) {
//include nullptr check to prevent segmentation error
if(!arr.a) return;
//dereference arr.a to access it
(*(arr.a))[0][0] = 10;
cout << (*(arr.a))[0][0] << endl; //dereference arr.a to access it
}
int main(int argc, const char * argv[]) {
vector<vector<double>> a(5, vector<double>(5));
buffer[0] = {&a};
modify(buffer[0]);
// want this to print 10
cout << a[0][0] << endl;
return 0;
}
Be careful to track the lifetime of the objects pointed to by the pointers, as if they go out of scope before the pointers do, the pointers will become dangling.
Upvotes: 1
Reputation: 1134
It's best to think of a reference as not an actual object, but an abstraction for "a way to access the object". Since it's not concrete data, it cannot be put into containers. Your best bet for achieving a similar effect is to create an array of pointers. Depending on your C++ standard and memory allocation needs you will need to choose between raw or C++11's smart pointers (from the <memory>
header).
Upvotes: 1