Reputation: 345
Am I right in thinking that this innocent looking code is rather dangerous?
template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), v.back());
}
some clarifications after reading some answers..
well I am not really asking how to insert an element into a vector but I made a dummy situation to question a principle.. In other words do you think it is necessary to make a copy (here a temporary is created.. and a const reference to a temporary is guaranteed to live):
template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), T(v.back()));
}
Upvotes: 4
Views: 254
Reputation: 37364
It seems dangerous to me as well because vector.back() returns reference, and
insertions on positions other than the vector end are performed by moving all the elements between position and the end of the vector to their new positions, and then inserting the new element(s) (from here)
Unless I misunderstood, reference passed to insert
becomes "invalid"(if no reallocation happens it can contain not the last element, but previous; otherwise it still may be correct, but I guess it's not guaranteed.
It's possible that in some cases some optimizers might hide the bug (my guess it never happens with objects, but may happen with primitives), so you get expected results, but in general I'd not rely on such behaviour.
Upvotes: 2
Reputation: 32398
Assuming that you addressed the two points mentioned in the comments to make this compile, this would and run but would leave a garbage value at the front of the vector every time it runs due to the fact that vector.back() returns a reference.
What it looks like this is trying to do is the following:
template<typename T>
void insertLast(std::vector<T>& v)
{
if(v.empty()) return;
v.insert(v.begin(), v.end() - 1, v.end());
}
This will safely insert the last element in the vector so that it's also the first element.... Assuming that is the desired behaviour.
Upvotes: 1