I did the following as a cheap way to allow read-only access to a member container _numbers
via numbers
:
class Foo {
Foo() : _numbers({}), numbers(_numbers) {
// some code that populates `numbers` via `numbers.push_back(...)`
}
private:
std::vector<int> _numbers;
public:
const std::vector<int>& numbers;
}
However, doing so I see that numbers
is empty, while in other cases it will contain the same elements as _numbers
.
To be more precise, it seems to be undefined behavior. In my real example (of which this a simplified version) I have multiple reference-container pairs with this scheme, where the populated data is visible in the const-reference member for some pairs, and for some it is not.
Any idea whats wrong with this? Any help is deeply appreciated.
EDIT Here is a minimal working example:
#include <vector>
struct Foo2 {
public:
const int max1;
const int center1;
Foo2(const int max1_);
private:
std::vector<int> _numbers1, _numbers2;
public:
const std::vector<int>& numbers1, numbers2;
};
Foo2::Foo2(const int max1_)
: max1(max1_), center1(max1_/2),
_numbers1({}), _numbers2({}),
numbers1(_numbers1),
numbers2(_numbers2)
{
cout << max1 << endl;
for (int i=0; i<center1; i++) {
_numbers1.push_back(i);
cout << "A: " << i << endl;
}
for (int i=center1; i<max1; i++) {
_numbers2.push_back(i);
cout << "B: " << i << endl;
}
for (int i: numbers1) {
cout << "A: " << i << endl;
}
for (int i: numbers2) {
cout << "B: " << i << endl;
}
}
which gives the following Output when initializing Foo2 f(8)
:
8
A: 0
A: 1
A: 2
A: 3
B: 4
B: 5
B: 6
B: 7
A: 0
A: 1
A: 2
A: 3
i.e. numbers2
does not see the contents of _numbers2
while for numbers1
it seems to work.
const vector<int>& numbers1, numbers2;
— Here, only the first variable is a reference. You need &
before the second variable to make it a reference as well. Then the code should work.
But I have to say that what you're doing is a really bad idea. You're paying for a convenient syntax with memory overhead, non-assignability, and possibly speed overhead.
Use getters instead: const vector<int>& numbers1() const {return _numbers1;}
. Yes, you will have to type the extra ()
every time.