Consider this hypothetical implementation of vector :
template<class T> // ignore the allocator struct vector { typedef T* iterator; typedef const T* const_iterator; template<class It> void insert(iterator where, It begin, It end) { ... } ... }
Problem
There is a subtle problem we are facing here:
It is likely that begin and end refer to elements in the same vector after where .
For example, if the user says:
vector<int> items; for (int i = 0; i < 1000; i++) items.push_back(i); items.insert(items.begin(), items.end() - 2, items.end() - 1);
If It not a pointer type, then we are fine.
But we donโt know, therefore we have to check that [begin, end) does not belong to the range already inside the vector.
But how do we do this? According to C ++, if they do not belong to the same array, then the pointer comparison will be undefined!
Thus, the compiler may erroneously tell us that the elements are not aliases when in fact they do this, which leads to an unnecessary slowdown of O (n).
Potential solution and disclaimer
One solution is to copy the entire vector each time, include new elements, and then delete the old copy.
But it is very slow in scenarios such as the example above, where we will copy 1000 elements to insert one element, although we might already have sufficient capacity.
Is there a general way (correctly) to solve this problem effectively, i.e. not suffer from a slowdown of O (n) in cases where nothing overlaps?
source share