Reputation: 6613
I have a need for a 3d vector to store some tile objects, rather than putting a vector inside a vector inside a vector I tried this:
inside a struct
...
vector<sortTile3> data;
uint32_t width, length, height;
sortTile3& At(uint32_t x, uint32_t y, uint32_t z) {
return data[x * width + y * length + z];
}
...
Seems to work fine, also should be faster, i think, because instead of 3 memory fetches it would do 1 memory fetch and 4 calculations or 2 calculations if i can figure out how to do a fused multiply add.
Anyway, I remember reading something on this very site about returning references being bad. I can see why.. a lot of things can go wrong but shouldn't be the case with this one..or?
Upvotes: 1
Views: 92
Reputation: 44043
This is fine and usual. The problem with returning a reference concerns (mostly) function-local objects. To wit:
struct foo {
int data;
// this is fine
int &ref1() {
return data;
}
// this is NOT fine
int &ref2() {
int localdata;
return localdata;
}
}
The reason the latter is not fine is that localdata
goes out of scope when foo::ref2
is left, and then the returned reference will not refer to a valid object.
Generally, you have to take care to not keep references to objects longer than their lifetime, but there is nothing inherently wrong with returning a reference to a data member from a member function.
You may, for example, have noticed that std::vector
's operator[]
returns a reference to its members; it is fine for you to do the same thing. You do, however, have to be careful not to store them longer than they remain valid. For example:
std::vector<int> v(10);
int &r = v[0];
v.resize(20);
// r is no longer valid because v may have relocated its storage.
Note also that there are certain things that you can only achieve by returning a reference. If you want, for example, to be able to do
yourstruct.At(0, 1, 2).foo = bar;
and have the change stick, returning a copy will not be useful to you.
Upvotes: 1
Reputation: 9090
There can be a problem if the reference gets stored (and not just used temporarily). The reference will get invalidated when the vector
reallocates memory or when items in the vector
get moved around (insert
), or when the vector
gets deleted. If the vector
is no longer modified after these references get stored, it will be safe.
See http://en.cppreference.com/w/cpp/container/vector on iterator invalidation.
Upvotes: 1