I have this code. scores
is a field in HiscoreTable
of type std::vector<reference_wrapper<Record>>
void HiscoreTable::replaceRecord(Record rec)
{
bool found = false;
for (reference_wrapper<Record> r : scores) {
if (r.get().name == rec.name) {
r = rec;
found = true;
break;
}
}
if (!found) {
scores.push_back(rec);
}
}
And if I try to do for(reference_wrapper<Record> r : scores) cout << r.get() << endl;
, a bad_alloc is thrown. Is it because r
is not a Record&
but a reference_wrapper<Record>
and therefore I cannot assign a Record
to it? I thought reference_wrapper<Record>::operator=
was overloaded to allow such a thing?
EDIT: Turns out it was a problem in my destructor, where the printing loop was located. At some point, I passed a HiscoreTable in to a helper function by value, and when it got destructed at the end of the helper function, it invalidated the callsite's HiscoreTable. I don't know why printing would break a reference, but I guess that's what happened.
For starters, you are creating a reference to a local object.
void HiscoreTable::replaceRecord(Record rec) { // 'rec' passed by value.
bool found = false;
for (reference_wrapper<Record> r : scores) {
if (r.get().name == rec.name) {
r = rec; // Reference to local object 'rec'.
/* ... */
} // 'rec' is destroyed and any reference to it will become dangling.
The assignment operator of std::reference_wrapper
will replace the internal "reference" with the one passed as argument, e.g.
r = rec; // Reference wrapper 'r' will contain pointer to 'rec'.
Instead pass rec
by reference. Also for the replacement to stick, you will need to change the type of r
in the for
-loop to be a reference. Otherwise you are assigning to a local copy.
for (reference_wrapper<Record>& r : scores) { // Type changed to reference.
/* ... */
}